aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/advancedDetector.cpp299
-rw-r--r--engines/advancedDetector.h203
-rw-r--r--engines/agi/agi.cpp37
-rw-r--r--engines/agi/detection.cpp36
-rw-r--r--engines/agi/predictive.cpp6
-rw-r--r--engines/agi/sound.cpp2
-rw-r--r--engines/agi/sound_2gs.cpp12
-rw-r--r--engines/agi/sound_2gs.h4
-rw-r--r--engines/agi/sound_midi.cpp10
-rw-r--r--engines/agi/sound_pcjr.cpp5
-rw-r--r--engines/agi/sound_pcjr.h4
-rw-r--r--engines/agi/sound_sarien.cpp4
-rw-r--r--engines/agi/text.cpp5
-rw-r--r--engines/agi/wagparser.cpp4
-rw-r--r--engines/agos/animation.cpp7
-rw-r--r--engines/agos/detection.cpp46
-rw-r--r--engines/agos/script_pn.cpp8
-rw-r--r--engines/agos/string.cpp12
-rw-r--r--engines/cine/detection.cpp44
-rw-r--r--engines/cine/prc.cpp4
-rw-r--r--engines/cine/various.cpp2
-rw-r--r--engines/cruise/background.cpp2
-rw-r--r--engines/cruise/cruise_main.cpp2
-rw-r--r--engines/cruise/detection.cpp30
-rw-r--r--engines/dialogs.cpp16
-rw-r--r--engines/draci/detection.cpp29
-rw-r--r--engines/draci/script.cpp4
-rw-r--r--engines/draci/sound.cpp13
-rw-r--r--engines/drascula/detection.cpp32
-rw-r--r--engines/drascula/graphics.cpp4
-rw-r--r--engines/drascula/interface.cpp2
-rw-r--r--engines/drascula/resource.cpp2
-rw-r--r--engines/drascula/rooms.cpp2
-rw-r--r--engines/dreamweb/README12
-rw-r--r--engines/dreamweb/console.cpp36
-rw-r--r--engines/dreamweb/console.h46
-rw-r--r--engines/dreamweb/detection.cpp147
-rw-r--r--engines/dreamweb/detection_tables.h157
-rw-r--r--engines/dreamweb/dreamgen.cpp22821
-rw-r--r--engines/dreamweb/dreamgen.h1345
-rw-r--r--engines/dreamweb/dreamweb.cpp635
-rw-r--r--engines/dreamweb/dreamweb.h158
-rw-r--r--engines/dreamweb/module.mk16
-rw-r--r--engines/dreamweb/runtime.h561
-rw-r--r--engines/dreamweb/stubs.cpp557
-rw-r--r--engines/engine.cpp48
-rw-r--r--engines/engine.h23
-rw-r--r--engines/engines.mk5
-rw-r--r--engines/game.cpp45
-rw-r--r--engines/game.h40
-rw-r--r--engines/gob/detection.cpp46
-rw-r--r--engines/gob/detection_tables.h52
-rw-r--r--engines/gob/inter_fascin.cpp2
-rw-r--r--engines/gob/inter_playtoons.cpp3
-rw-r--r--engines/gob/inter_v2.cpp5
-rw-r--r--engines/gob/inter_v5.cpp4
-rw-r--r--engines/gob/video_v6.cpp2
-rw-r--r--engines/groovie/detection.cpp55
-rw-r--r--engines/groovie/music.cpp8
-rw-r--r--engines/groovie/player.h4
-rw-r--r--engines/groovie/script.cpp3
-rw-r--r--engines/hugo/console.cpp12
-rw-r--r--engines/hugo/detection.cpp28
-rw-r--r--engines/hugo/dialogs.cpp10
-rw-r--r--engines/hugo/display.cpp2
-rw-r--r--engines/hugo/file_v1d.cpp2
-rw-r--r--engines/hugo/file_v1w.cpp2
-rw-r--r--engines/hugo/file_v2d.cpp2
-rw-r--r--engines/hugo/file_v3d.cpp4
-rw-r--r--engines/hugo/hugo.cpp6
-rw-r--r--engines/hugo/hugo.h2
-rw-r--r--engines/hugo/inventory.h2
-rw-r--r--engines/hugo/object.cpp4
-rw-r--r--engines/hugo/parser.cpp6
-rw-r--r--engines/hugo/parser.h4
-rw-r--r--engines/hugo/schedule.cpp4
-rw-r--r--engines/hugo/schedule.h2
-rw-r--r--engines/hugo/sound.cpp4
-rw-r--r--engines/hugo/util.cpp2
-rw-r--r--engines/kyra/animator_mr.cpp7
-rw-r--r--engines/kyra/debugger.cpp9
-rw-r--r--engines/kyra/detection.cpp32
-rw-r--r--engines/kyra/detection_tables.h105
-rw-r--r--engines/kyra/gui.cpp19
-rw-r--r--engines/kyra/gui_lol.cpp15
-rw-r--r--engines/kyra/gui_mr.cpp20
-rw-r--r--engines/kyra/kyra_hof.cpp8
-rw-r--r--engines/kyra/kyra_lok.cpp8
-rw-r--r--engines/kyra/kyra_mr.cpp41
-rw-r--r--engines/kyra/kyra_mr.h2
-rw-r--r--engines/kyra/kyra_v1.cpp1
-rw-r--r--engines/kyra/kyra_v1.h21
-rw-r--r--engines/kyra/lol.cpp72
-rw-r--r--engines/kyra/lol.h2
-rw-r--r--engines/kyra/saveload_hof.cpp2
-rw-r--r--engines/kyra/saveload_lok.cpp2
-rw-r--r--engines/kyra/saveload_lol.cpp2
-rw-r--r--engines/kyra/saveload_mr.cpp2
-rw-r--r--engines/kyra/scene_lol.cpp42
-rw-r--r--engines/kyra/script_lol.cpp44
-rw-r--r--engines/kyra/script_tim.cpp26
-rw-r--r--engines/kyra/sequences_lol.cpp9
-rw-r--r--engines/kyra/sound_intern.h2
-rw-r--r--engines/kyra/sound_lok.cpp5
-rw-r--r--engines/kyra/sound_lol.cpp40
-rw-r--r--engines/kyra/sound_midi.cpp5
-rw-r--r--engines/kyra/sound_towns.cpp12
-rw-r--r--engines/kyra/staticres.cpp2
-rw-r--r--engines/kyra/text_hof.cpp9
-rw-r--r--engines/kyra/text_mr.cpp12
-rw-r--r--engines/lastexpress/data/animation.cpp12
-rw-r--r--engines/lastexpress/data/background.cpp2
-rw-r--r--engines/lastexpress/data/font.cpp8
-rw-r--r--engines/lastexpress/data/scene.cpp8
-rw-r--r--engines/lastexpress/data/sequence.cpp14
-rw-r--r--engines/lastexpress/data/snd.cpp4
-rw-r--r--engines/lastexpress/data/subtitle.cpp4
-rw-r--r--engines/lastexpress/debug.cpp11
-rw-r--r--engines/lastexpress/detection.cpp73
-rw-r--r--engines/lastexpress/entities/abbot.cpp10
-rw-r--r--engines/lastexpress/entities/alexei.cpp3
-rw-r--r--engines/lastexpress/entities/alouan.cpp3
-rw-r--r--engines/lastexpress/entities/anna.cpp65
-rw-r--r--engines/lastexpress/entities/august.cpp28
-rw-r--r--engines/lastexpress/entities/boutarel.cpp8
-rw-r--r--engines/lastexpress/entities/chapters.cpp147
-rw-r--r--engines/lastexpress/entities/cooks.cpp8
-rw-r--r--engines/lastexpress/entities/coudert.cpp26
-rw-r--r--engines/lastexpress/entities/entity.cpp15
-rw-r--r--engines/lastexpress/entities/entity.h24
-rw-r--r--engines/lastexpress/entities/entity_intern.h4
-rw-r--r--engines/lastexpress/entities/francois.cpp12
-rw-r--r--engines/lastexpress/entities/gendarmes.cpp18
-rw-r--r--engines/lastexpress/entities/gendarmes.h4
-rw-r--r--engines/lastexpress/entities/hadija.cpp3
-rw-r--r--engines/lastexpress/entities/ivo.cpp6
-rw-r--r--engines/lastexpress/entities/kahina.cpp18
-rw-r--r--engines/lastexpress/entities/kronos.cpp16
-rw-r--r--engines/lastexpress/entities/mahmud.cpp24
-rw-r--r--engines/lastexpress/entities/max.cpp48
-rw-r--r--engines/lastexpress/entities/mertens.cpp26
-rw-r--r--engines/lastexpress/entities/milos.cpp29
-rw-r--r--engines/lastexpress/entities/mmeboutarel.cpp10
-rw-r--r--engines/lastexpress/entities/pascale.cpp24
-rw-r--r--engines/lastexpress/entities/rebecca.cpp10
-rw-r--r--engines/lastexpress/entities/salko.cpp11
-rw-r--r--engines/lastexpress/entities/servers0.cpp3
-rw-r--r--engines/lastexpress/entities/servers1.cpp3
-rw-r--r--engines/lastexpress/entities/sophie.cpp3
-rw-r--r--engines/lastexpress/entities/tables.cpp22
-rw-r--r--engines/lastexpress/entities/tatiana.cpp30
-rw-r--r--engines/lastexpress/entities/train.cpp50
-rw-r--r--engines/lastexpress/entities/vassili.cpp10
-rw-r--r--engines/lastexpress/entities/verges.cpp32
-rw-r--r--engines/lastexpress/entities/vesna.cpp10
-rw-r--r--engines/lastexpress/entities/yasmin.cpp3
-rw-r--r--engines/lastexpress/fight/fight.cpp409
-rw-r--r--engines/lastexpress/fight/fight.h125
-rw-r--r--engines/lastexpress/fight/fighter.cpp249
-rw-r--r--engines/lastexpress/fight/fighter.h123
-rw-r--r--engines/lastexpress/fight/fighter_anna.cpp187
-rw-r--r--engines/lastexpress/fight/fighter_anna.h48
-rw-r--r--engines/lastexpress/fight/fighter_ivo.cpp245
-rw-r--r--engines/lastexpress/fight/fighter_ivo.h51
-rw-r--r--engines/lastexpress/fight/fighter_milos.cpp222
-rw-r--r--engines/lastexpress/fight/fighter_milos.h51
-rw-r--r--engines/lastexpress/fight/fighter_salko.cpp202
-rw-r--r--engines/lastexpress/fight/fighter_salko.h51
-rw-r--r--engines/lastexpress/fight/fighter_vesna.cpp265
-rw-r--r--engines/lastexpress/fight/fighter_vesna.h51
-rw-r--r--engines/lastexpress/game/action.cpp72
-rw-r--r--engines/lastexpress/game/beetle.cpp14
-rw-r--r--engines/lastexpress/game/entities.cpp28
-rw-r--r--engines/lastexpress/game/fight.cpp1583
-rw-r--r--engines/lastexpress/game/fight.h266
-rw-r--r--engines/lastexpress/game/inventory.cpp19
-rw-r--r--engines/lastexpress/game/logic.cpp29
-rw-r--r--engines/lastexpress/game/object.cpp2
-rw-r--r--engines/lastexpress/game/savegame.cpp69
-rw-r--r--engines/lastexpress/game/savepoint.cpp6
-rw-r--r--engines/lastexpress/game/scenes.cpp24
-rw-r--r--engines/lastexpress/game/sound.h389
-rw-r--r--engines/lastexpress/game/state.cpp2
-rw-r--r--engines/lastexpress/game/state.h2
-rw-r--r--engines/lastexpress/graphics.cpp6
-rw-r--r--engines/lastexpress/helpers.h1
-rw-r--r--engines/lastexpress/lastexpress.cpp37
-rw-r--r--engines/lastexpress/lastexpress.h5
-rw-r--r--engines/lastexpress/menu/clock.cpp106
-rw-r--r--engines/lastexpress/menu/clock.h53
-rw-r--r--engines/lastexpress/menu/menu.cpp (renamed from engines/lastexpress/game/menu.cpp)274
-rw-r--r--engines/lastexpress/menu/menu.h (renamed from engines/lastexpress/game/menu.h)0
-rw-r--r--engines/lastexpress/menu/trainline.cpp142
-rw-r--r--engines/lastexpress/menu/trainline.h51
-rw-r--r--engines/lastexpress/module.mk16
-rw-r--r--engines/lastexpress/resource.cpp4
-rw-r--r--engines/lastexpress/shared.h62
-rw-r--r--engines/lastexpress/sound/entry.cpp396
-rw-r--r--engines/lastexpress/sound/entry.h220
-rw-r--r--engines/lastexpress/sound/queue.cpp793
-rw-r--r--engines/lastexpress/sound/queue.h131
-rw-r--r--engines/lastexpress/sound/sound.cpp (renamed from engines/lastexpress/game/sound.cpp)876
-rw-r--r--engines/lastexpress/sound/sound.h87
-rw-r--r--engines/lure/debugger.cpp14
-rw-r--r--engines/lure/detection.cpp35
-rw-r--r--engines/lure/memory.cpp8
-rw-r--r--engines/lure/res_struct.h2
-rw-r--r--engines/m4/animation.cpp18
-rw-r--r--engines/m4/assets.cpp8
-rw-r--r--engines/m4/assets.h4
-rw-r--r--engines/m4/detection.cpp70
-rw-r--r--engines/m4/dialogs.cpp6
-rw-r--r--engines/m4/events.cpp2
-rw-r--r--engines/m4/font.h2
-rw-r--r--engines/m4/globals.cpp4
-rw-r--r--engines/m4/graphics.cpp12
-rw-r--r--engines/m4/graphics.h2
-rw-r--r--engines/m4/m4.cpp2
-rw-r--r--engines/m4/m4.h2
-rw-r--r--engines/m4/m4_menus.cpp3
-rw-r--r--engines/m4/m4_views.cpp2
-rw-r--r--engines/m4/mads_anim.cpp2
-rw-r--r--engines/m4/mads_logic.cpp32
-rw-r--r--engines/m4/mads_logic.h4
-rw-r--r--engines/m4/mads_menus.cpp10
-rw-r--r--engines/m4/mads_player.cpp18
-rw-r--r--engines/m4/mads_scene.cpp20
-rw-r--r--engines/m4/mads_views.cpp40
-rw-r--r--engines/m4/mads_views.h12
-rw-r--r--engines/m4/resource.cpp2
-rw-r--r--engines/m4/resource.h2
-rw-r--r--engines/m4/scene.cpp6
-rw-r--r--engines/m4/sound.cpp4
-rw-r--r--engines/m4/sprite.cpp2
-rw-r--r--engines/made/database.cpp8
-rw-r--r--engines/made/detection.cpp33
-rw-r--r--engines/module.mk1
-rw-r--r--engines/mohawk/bitmap.cpp2
-rw-r--r--engines/mohawk/console.cpp2
-rw-r--r--engines/mohawk/cstime.cpp2
-rw-r--r--engines/mohawk/cursors.cpp3
-rw-r--r--engines/mohawk/detection.cpp35
-rw-r--r--engines/mohawk/detection_tables.h133
-rw-r--r--engines/mohawk/livingbooks.cpp192
-rw-r--r--engines/mohawk/livingbooks.h51
-rw-r--r--engines/mohawk/livingbooks_code.cpp35
-rw-r--r--engines/mohawk/mohawk.h11
-rw-r--r--engines/mohawk/myst.cpp4
-rw-r--r--engines/mohawk/myst_scripts.cpp178
-rw-r--r--engines/mohawk/myst_stacks/demo.cpp2
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp4
-rw-r--r--engines/mohawk/resource.cpp602
-rw-r--r--engines/mohawk/resource.h146
-rw-r--r--engines/mohawk/riven.cpp25
-rw-r--r--engines/mohawk/riven.h2
-rw-r--r--engines/mohawk/riven_external.cpp8
-rw-r--r--engines/mohawk/riven_saveload.cpp93
-rw-r--r--engines/mohawk/riven_scripts.cpp34
-rw-r--r--engines/mohawk/riven_scripts.h4
-rw-r--r--engines/mohawk/video.cpp20
-rw-r--r--engines/obsolete.cpp88
-rw-r--r--engines/obsolete.h78
-rw-r--r--engines/parallaction/detection.cpp29
-rw-r--r--engines/parallaction/dialogue.cpp28
-rw-r--r--engines/parallaction/exec_br.cpp6
-rw-r--r--engines/parallaction/gfxbase.cpp10
-rw-r--r--engines/parallaction/graphics.cpp6
-rw-r--r--engines/parallaction/gui_br.cpp4
-rw-r--r--engines/parallaction/gui_ns.cpp22
-rw-r--r--engines/parallaction/objects.cpp8
-rw-r--r--engines/parallaction/parallaction.cpp10
-rw-r--r--engines/parallaction/parallaction_ns.cpp4
-rw-r--r--engines/parallaction/parser_br.cpp16
-rw-r--r--engines/parallaction/parser_ns.cpp10
-rw-r--r--engines/parallaction/saveload.cpp19
-rw-r--r--engines/parallaction/sound.h4
-rw-r--r--engines/parallaction/sound_ns.cpp8
-rw-r--r--engines/parallaction/walk.cpp6
-rw-r--r--engines/queen/talk.cpp2
-rw-r--r--engines/saga/actor.cpp3
-rw-r--r--engines/saga/actor.h4
-rw-r--r--engines/saga/actor_walk.cpp10
-rw-r--r--engines/saga/animation.cpp4
-rw-r--r--engines/saga/detection.cpp42
-rw-r--r--engines/saga/detection_tables.h4
-rw-r--r--engines/saga/events.cpp2
-rw-r--r--engines/saga/introproc_saga2.cpp2
-rw-r--r--engines/saga/isomap.cpp2
-rw-r--r--engines/saga/palanim.cpp4
-rw-r--r--engines/saga/saga.cpp2
-rw-r--r--engines/saga/scene.h2
-rw-r--r--engines/saga/sprite.cpp8
-rw-r--r--engines/sci/console.cpp190
-rw-r--r--engines/sci/console.h2
-rw-r--r--engines/sci/decompressor.cpp46
-rw-r--r--engines/sci/detection.cpp158
-rw-r--r--engines/sci/detection_tables.h197
-rw-r--r--engines/sci/engine/features.h2
-rw-r--r--engines/sci/engine/kernel.h2
-rw-r--r--engines/sci/engine/kernel_tables.h6
-rw-r--r--engines/sci/engine/kevent.cpp2
-rw-r--r--engines/sci/engine/kfile.cpp6
-rw-r--r--engines/sci/engine/kgraphics.cpp12
-rw-r--r--engines/sci/engine/kmisc.cpp6
-rw-r--r--engines/sci/engine/kmovement.cpp4
-rw-r--r--engines/sci/engine/kpathing.cpp6
-rw-r--r--engines/sci/engine/kscripts.cpp2
-rw-r--r--engines/sci/engine/kstring.cpp12
-rw-r--r--engines/sci/engine/kvideo.cpp6
-rw-r--r--engines/sci/engine/object.cpp10
-rw-r--r--engines/sci/engine/object.h4
-rw-r--r--engines/sci/engine/savegame.h2
-rw-r--r--engines/sci/engine/script.cpp2
-rw-r--r--engines/sci/engine/script_patches.cpp10
-rw-r--r--engines/sci/engine/scriptdebug.cpp22
-rw-r--r--engines/sci/engine/segment.cpp2
-rw-r--r--engines/sci/engine/selector.cpp2
-rw-r--r--engines/sci/engine/selector.h2
-rw-r--r--engines/sci/engine/state.cpp4
-rw-r--r--engines/sci/engine/static_selectors.cpp8
-rw-r--r--engines/sci/engine/vm.cpp38
-rw-r--r--engines/sci/engine/vm_types.cpp14
-rw-r--r--engines/sci/engine/workarounds.cpp4
-rw-r--r--engines/sci/event.cpp4
-rw-r--r--engines/sci/graphics/animate.cpp4
-rw-r--r--engines/sci/graphics/compare.cpp9
-rw-r--r--engines/sci/graphics/compare.h2
-rw-r--r--engines/sci/graphics/controls.cpp1
-rw-r--r--engines/sci/graphics/coordadjuster.h4
-rw-r--r--engines/sci/graphics/menu.cpp4
-rw-r--r--engines/sci/graphics/palette.cpp8
-rw-r--r--engines/sci/graphics/palette.h2
-rw-r--r--engines/sci/graphics/picture.cpp8
-rw-r--r--engines/sci/graphics/ports.cpp2
-rw-r--r--engines/sci/graphics/text16.cpp2
-rw-r--r--engines/sci/graphics/transitions.cpp8
-rw-r--r--engines/sci/graphics/view.cpp10
-rw-r--r--engines/sci/parser/said.cpp10
-rw-r--r--engines/sci/resource.cpp30
-rw-r--r--engines/sci/resource_audio.cpp6
-rw-r--r--engines/sci/sci.cpp7
-rw-r--r--engines/sci/sci.h4
-rw-r--r--engines/sci/sound/audio.cpp2
-rw-r--r--engines/sci/sound/drivers/amigamac.cpp52
-rw-r--r--engines/sci/sound/music.cpp4
-rw-r--r--engines/sci/video/robot_decoder.cpp24
-rw-r--r--engines/sci/video/seq_decoder.h2
-rw-r--r--engines/scumm/actor.cpp2
-rw-r--r--engines/scumm/charset.cpp11
-rw-r--r--engines/scumm/costume.cpp10
-rw-r--r--engines/scumm/cursor.cpp6
-rw-r--r--engines/scumm/detection.cpp30
-rw-r--r--engines/scumm/detection_tables.h4
-rw-r--r--engines/scumm/gfx.cpp47
-rw-r--r--engines/scumm/gfx.h23
-rw-r--r--engines/scumm/gfx_towns.cpp89
-rw-r--r--engines/scumm/he/logic_he.cpp2
-rw-r--r--engines/scumm/he/resource_he.cpp2
-rw-r--r--engines/scumm/he/resource_he.h2
-rw-r--r--engines/scumm/he/script_v60he.cpp2
-rw-r--r--engines/scumm/he/script_v72he.cpp2
-rw-r--r--engines/scumm/imuse/imuse.cpp13
-rw-r--r--engines/scumm/imuse/imuse_internal.h2
-rw-r--r--engines/scumm/imuse/imuse_player.cpp6
-rw-r--r--engines/scumm/imuse/sysex_scumm.cpp2
-rw-r--r--engines/scumm/input.cpp2
-rw-r--r--engines/scumm/palette.cpp6
-rw-r--r--engines/scumm/player_towns.cpp56
-rw-r--r--engines/scumm/player_towns.h12
-rw-r--r--engines/scumm/resource.cpp7
-rw-r--r--engines/scumm/resource.h6
-rw-r--r--engines/scumm/saveload.cpp16
-rw-r--r--engines/scumm/script_v5.cpp4
-rw-r--r--engines/scumm/scumm.cpp92
-rw-r--r--engines/scumm/scumm.h10
-rw-r--r--engines/scumm/smush/smush_player.cpp4
-rw-r--r--engines/scumm/sound.cpp2
-rw-r--r--engines/scumm/string.cpp8
-rw-r--r--engines/scumm/verbs.cpp18
-rw-r--r--engines/sky/compact.cpp7
-rw-r--r--engines/sky/detection.cpp2
-rw-r--r--engines/sword1/animation.cpp14
-rw-r--r--engines/sword1/control.cpp12
-rw-r--r--engines/sword1/detection.cpp48
-rw-r--r--engines/sword1/logic.cpp3
-rw-r--r--engines/sword1/music.cpp68
-rw-r--r--engines/sword1/music.h2
-rw-r--r--engines/sword2/animation.cpp12
-rw-r--r--engines/sword25/detection.cpp34
-rw-r--r--engines/sword25/detection_tables.h20
-rw-r--r--engines/sword25/fmv/theora_decoder.cpp17
-rw-r--r--engines/sword25/gfx/animation.h2
-rw-r--r--engines/sword25/gfx/animationresource.cpp6
-rw-r--r--engines/sword25/gfx/fontresource.cpp2
-rw-r--r--engines/sword25/gfx/graphicengine.cpp2
-rw-r--r--engines/sword25/gfx/image/art.cpp71
-rw-r--r--engines/sword25/gfx/image/art.h5
-rw-r--r--engines/sword25/gfx/image/renderedimage.cpp24
-rw-r--r--engines/sword25/gfx/image/vectorimage.cpp2
-rw-r--r--engines/sword25/gfx/image/vectorimagerenderer.cpp7
-rw-r--r--engines/sword25/gfx/screenshot.cpp6
-rw-r--r--engines/sword25/gfx/staticbitmap.cpp5
-rw-r--r--engines/sword25/gfx/text.cpp2
-rw-r--r--engines/sword25/kernel/persistenceservice.cpp2
-rw-r--r--engines/sword25/package/packagemanager.cpp2
-rw-r--r--engines/sword25/package/packagemanager.h5
-rw-r--r--engines/sword25/sfx/soundengine.cpp138
-rw-r--r--engines/sword25/sfx/soundengine.h7
-rw-r--r--engines/sword25/util/lua/lapi.cpp4
-rw-r--r--engines/sword25/util/lua/lauxlib.cpp8
-rw-r--r--engines/sword25/util/lua/ldblib.cpp2
-rw-r--r--engines/sword25/util/lua/ldebug.cpp2
-rw-r--r--engines/sword25/util/lua/ldo.cpp2
-rw-r--r--engines/sword25/util/lua/lgc.cpp4
-rw-r--r--engines/sword25/util/lua/liolib.cpp42
-rw-r--r--engines/sword25/util/lua/llex.cpp2
-rw-r--r--engines/sword25/util/lua/llimits.h4
-rw-r--r--engines/sword25/util/lua/loadlib.cpp4
-rw-r--r--engines/sword25/util/lua/lobject.h2
-rw-r--r--engines/sword25/util/lua/lopcodes.h10
-rw-r--r--engines/sword25/util/lua/lstate.cpp2
-rw-r--r--engines/sword25/util/lua/lstrlib.cpp2
-rw-r--r--engines/sword25/util/lua/ltable.cpp14
-rw-r--r--engines/sword25/util/lua/lua.h2
-rw-r--r--engines/sword25/util/lua/lualib.h2
-rw-r--r--engines/sword25/util/lua/lvm.cpp4
-rw-r--r--engines/sword25/util/lua/scummvm_file.cpp48
-rw-r--r--engines/sword25/util/lua/scummvm_file.h1
-rw-r--r--engines/teenagent/animation.cpp4
-rw-r--r--engines/teenagent/detection.cpp35
-rw-r--r--engines/teenagent/inventory.cpp2
-rw-r--r--engines/teenagent/inventory.h4
-rw-r--r--engines/teenagent/resources.cpp11
-rw-r--r--engines/teenagent/resources.h6
-rw-r--r--engines/teenagent/scene.cpp8
-rw-r--r--engines/teenagent/teenagent.cpp135
-rw-r--r--engines/testbed/config-params.h10
-rw-r--r--engines/testbed/config.cpp16
-rw-r--r--engines/testbed/config.h6
-rw-r--r--engines/testbed/detection.cpp31
-rw-r--r--engines/testbed/fs.cpp4
-rw-r--r--engines/testbed/graphics.cpp26
-rw-r--r--engines/testbed/graphics.h4
-rw-r--r--engines/testbed/midi.cpp4
-rw-r--r--engines/testbed/misc.cpp2
-rw-r--r--engines/testbed/misc.h2
-rw-r--r--engines/testbed/savegame.cpp14
-rw-r--r--engines/testbed/sound.h4
-rw-r--r--engines/testbed/testbed.cpp8
-rw-r--r--engines/testbed/testsuite.cpp5
-rw-r--r--engines/testbed/testsuite.h6
-rw-r--r--engines/tinsel/coroutine.h17
-rw-r--r--engines/tinsel/detection.cpp43
-rw-r--r--engines/tinsel/detection_tables.h6
-rw-r--r--engines/tinsel/pcode.cpp8
-rw-r--r--engines/tinsel/saveload.cpp7
-rw-r--r--engines/tinsel/sched.cpp9
-rw-r--r--engines/tinsel/tinlib.cpp42
-rw-r--r--engines/toon/anim.cpp12
-rw-r--r--engines/toon/anim.h1
-rw-r--r--engines/toon/detection.cpp37
-rw-r--r--engines/toon/font.cpp14
-rw-r--r--engines/toon/path.cpp28
-rw-r--r--engines/toon/tools.cpp2
-rw-r--r--engines/toon/toon.cpp5
-rw-r--r--engines/toon/toon.h9
-rw-r--r--engines/touche/detection.cpp50
-rw-r--r--engines/touche/menu.cpp2
-rw-r--r--engines/touche/resource.cpp22
-rw-r--r--engines/touche/touche.h2
-rw-r--r--engines/tsage/blueforce_logic.cpp2
-rw-r--r--engines/tsage/converse.cpp2
-rw-r--r--engines/tsage/converse.h3
-rw-r--r--engines/tsage/core.cpp276
-rw-r--r--engines/tsage/core.h75
-rw-r--r--engines/tsage/debugger.cpp8
-rw-r--r--engines/tsage/detection.cpp21
-rw-r--r--engines/tsage/detection_tables.h61
-rw-r--r--engines/tsage/dialogs.cpp2
-rw-r--r--engines/tsage/events.cpp5
-rw-r--r--engines/tsage/events.h1
-rw-r--r--engines/tsage/globals.cpp19
-rw-r--r--engines/tsage/globals.h8
-rw-r--r--engines/tsage/graphics.cpp8
-rw-r--r--engines/tsage/resources.cpp15
-rw-r--r--engines/tsage/ringworld_demo.cpp9
-rw-r--r--engines/tsage/ringworld_demo.h3
-rw-r--r--engines/tsage/ringworld_logic.cpp57
-rw-r--r--engines/tsage/ringworld_scenes1.cpp153
-rw-r--r--engines/tsage/ringworld_scenes1.h25
-rw-r--r--engines/tsage/ringworld_scenes10.cpp43
-rw-r--r--engines/tsage/ringworld_scenes10.h8
-rw-r--r--engines/tsage/ringworld_scenes2.cpp37
-rw-r--r--engines/tsage/ringworld_scenes2.h4
-rw-r--r--engines/tsage/ringworld_scenes3.cpp254
-rw-r--r--engines/tsage/ringworld_scenes3.h20
-rw-r--r--engines/tsage/ringworld_scenes4.cpp8
-rw-r--r--engines/tsage/ringworld_scenes4.h2
-rw-r--r--engines/tsage/ringworld_scenes5.cpp94
-rw-r--r--engines/tsage/ringworld_scenes5.h10
-rw-r--r--engines/tsage/ringworld_scenes6.cpp36
-rw-r--r--engines/tsage/ringworld_scenes6.h8
-rw-r--r--engines/tsage/ringworld_scenes8.cpp49
-rw-r--r--engines/tsage/ringworld_scenes8.h14
-rw-r--r--engines/tsage/saveload.cpp6
-rw-r--r--engines/tsage/saveload.h2
-rw-r--r--engines/tsage/scenes.cpp11
-rw-r--r--engines/tsage/scenes.h4
-rw-r--r--engines/tsage/sound.cpp2987
-rw-r--r--engines/tsage/sound.h470
-rw-r--r--engines/tsage/tsage.cpp11
-rw-r--r--engines/tsage/tsage.h6
-rw-r--r--engines/tucker/detection.cpp31
513 files changed, 39606 insertions, 7880 deletions
diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp
index 2ee32b2f86..d864fe8b52 100644
--- a/engines/advancedDetector.cpp
+++ b/engines/advancedDetector.cpp
@@ -32,112 +32,7 @@
#include "common/translation.h"
#include "engines/advancedDetector.h"
-
-/**
- * A list of pointers to ADGameDescription structs (or subclasses thereof).
- */
-typedef Common::Array<const ADGameDescription*> ADGameDescList;
-
-
-/**
- * Detect games in specified directory.
- * Parameters language and platform are used to pass on values
- * specified by the user. I.e. this is used to restrict search scope.
- *
- * @param fslist FSList to scan or NULL for scanning all specified
- * default directories.
- * @param params a ADParams struct containing various parameters
- * @param language restrict results to specified language only
- * @param platform restrict results to specified platform only
- * @return list of ADGameDescription (or subclass) pointers corresponding to matched games
- */
-static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &params, Common::Language language, Common::Platform platform, const Common::String &extra);
-
-
-/**
- * Returns list of targets supported by the engine.
- * Distinguishes engines with single ID
- */
-static GameList gameIDList(const ADParams &params) {
- if (params.singleid != NULL) {
- GameList gl;
-
- const PlainGameDescriptor *g = params.list;
- while (g->gameid) {
- if (0 == scumm_stricmp(params.singleid, g->gameid)) {
- gl.push_back(GameDescriptor(g->gameid, g->description));
-
- return gl;
- }
- g++;
- }
- error("Engine %s doesn't have its singleid specified in ids list", params.singleid);
- }
-
- return GameList(params.list);
-}
-
-static void upgradeTargetIfNecessary(const ADParams &params) {
- if (params.obsoleteList == 0)
- return;
-
- Common::String gameid = ConfMan.get("gameid");
-
- for (const ADObsoleteGameID *o = params.obsoleteList; o->from; ++o) {
- if (gameid.equalsIgnoreCase(o->from)) {
- gameid = o->to;
- ConfMan.set("gameid", gameid);
-
- if (o->platform != Common::kPlatformUnknown)
- ConfMan.set("platform", Common::getPlatformCode(o->platform));
-
- warning("Target upgraded from %s to %s", o->from, o->to);
-
- // WORKAROUND: Fix for bug #1719463: "DETECTOR: Launching
- // undefined target adds launcher entry"
- if (ConfMan.hasKey("id_came_from_command_line")) {
- warning("Target came from command line. Skipping save");
- } else {
- ConfMan.flushToDisk();
- }
- break;
- }
- }
-}
-
-namespace AdvancedDetector {
-
-GameDescriptor findGameID(
- const char *gameid,
- const PlainGameDescriptor *list,
- const ADObsoleteGameID *obsoleteList
- ) {
- // First search the list of supported game IDs for a match.
- const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, list);
- if (g)
- return GameDescriptor(*g);
-
- // If we didn't find the gameid in the main list, check if it
- // is an obsolete game id.
- if (obsoleteList != 0) {
- const ADObsoleteGameID *o = obsoleteList;
- while (o->from) {
- if (0 == scumm_stricmp(gameid, o->from)) {
- g = findPlainGameDescriptor(o->to, list);
- if (g && g->description)
- return GameDescriptor(gameid, "Obsolete game ID (" + Common::String(g->description) + ")");
- else
- return GameDescriptor(gameid, "Obsolete game ID");
- }
- o++;
- }
- }
-
- // No match found
- return GameDescriptor();
-}
-
-} // End of namespace AdvancedDetector
+#include "engines/obsolete.h"
static GameDescriptor toGameDescriptor(const ADGameDescription &g, const PlainGameDescriptor *sg) {
const char *title = 0;
@@ -156,7 +51,13 @@ static GameDescriptor toGameDescriptor(const ADGameDescription &g, const PlainGa
extra = g.extra;
}
- GameDescriptor gd(g.gameid, title, g.language, g.platform);
+ GameSupportLevel gsl = kStableGame;
+ if (g.flags & ADGF_UNSTABLE)
+ gsl = kUnstableGame;
+ else if (g.flags & ADGF_TESTING)
+ gsl = kTestingGame;
+
+ GameDescriptor gd(g.gameid, title, g.language, g.platform, 0, gsl);
gd.updateDesc(extra);
return gd;
}
@@ -189,10 +90,10 @@ static Common::String generatePreferredTarget(const Common::String &id, const AD
return res;
}
-static void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *realDesc, const ADParams &params) {
- if (params.singleid != NULL) {
+void AdvancedMetaEngine::updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *realDesc) const {
+ if (_singleid != NULL) {
desc["preferredtarget"] = desc["gameid"];
- desc["gameid"] = params.singleid;
+ desc["gameid"] = _singleid;
}
if (!desc.contains("preferredtarget"))
@@ -200,10 +101,10 @@ static void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *
desc["preferredtarget"] = generatePreferredTarget(desc["preferredtarget"], realDesc);
- if (params.flags & kADFlagUseExtraAsHint)
+ if (_flags & kADFlagUseExtraAsHint)
desc["extra"] = realDesc->extra;
- desc.setGUIOptions(realDesc->guioptions | params.guioptions);
+ desc.setGUIOptions(realDesc->guioptions | _guioptions);
desc.appendGUIOptions(getGameGUIOptionsDescriptionLanguage(realDesc->language));
if (realDesc->flags & ADGF_ADDENGLISH)
@@ -211,7 +112,7 @@ static void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *
}
bool cleanupPirated(ADGameDescList &matched) {
- // OKay, now let's sense presense of pirated games
+ // OKay, now let's sense presence of pirated games
if (!matched.empty()) {
for (uint j = 0; j < matched.size();) {
if (matched[j]->flags & ADGF_PIRATED)
@@ -222,9 +123,7 @@ bool cleanupPirated(ADGameDescList &matched) {
// We ruled out all variants and now have nothing
if (matched.empty()) {
-
warning("Illegitimate game copy detected. We give no support in such cases %d", matched.size());
-
return true;
}
}
@@ -234,25 +133,33 @@ bool cleanupPirated(ADGameDescList &matched) {
GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const {
- ADGameDescList matches = detectGame(fslist, params, Common::UNK_LANG, Common::kPlatformUnknown, "");
+ ADGameDescList matches;
GameList detectedGames;
+ FileMap allFiles;
- if (cleanupPirated(matches))
+ if (fslist.empty())
return detectedGames;
+ // Compose a hashmap of all files in fslist.
+ composeFileHashMap(allFiles, fslist, (_maxScanDepth == 0 ? 1 : _maxScanDepth));
+
+ // Run the detector on this
+ matches = detectGame(fslist.begin()->getParent(), allFiles, Common::UNK_LANG, Common::kPlatformUnknown, "");
+
if (matches.empty()) {
// Use fallback detector if there were no matches by other means
- const ADGameDescription *fallbackDesc = fallbackDetect(fslist);
+ const ADGameDescription *fallbackDesc = fallbackDetect(allFiles, fslist);
if (fallbackDesc != 0) {
- GameDescriptor desc(toGameDescriptor(*fallbackDesc, params.list));
- updateGameDescriptor(desc, fallbackDesc, params);
+ GameDescriptor desc(toGameDescriptor(*fallbackDesc, _gameids));
+ updateGameDescriptor(desc, fallbackDesc);
detectedGames.push_back(desc);
}
} else {
// Otherwise use the found matches
+ cleanupPirated(matches);
for (uint i = 0; i < matches.size(); i++) {
- GameDescriptor desc(toGameDescriptor(*matches[i], params.list));
- updateGameDescriptor(desc, matches[i], params);
+ GameDescriptor desc(toGameDescriptor(*matches[i], _gameids));
+ updateGameDescriptor(desc, matches[i]);
detectedGames.push_back(desc);
}
}
@@ -262,7 +169,6 @@ GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const {
Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(engine);
- upgradeTargetIfNecessary(params);
const ADGameDescription *agdDesc = 0;
Common::Language language = Common::UNK_LANG;
@@ -273,9 +179,10 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
language = Common::parseLanguage(ConfMan.get("language"));
if (ConfMan.hasKey("platform"))
platform = Common::parsePlatform(ConfMan.get("platform"));
- if (params.flags & kADFlagUseExtraAsHint)
+ if (_flags & kADFlagUseExtraAsHint) {
if (ConfMan.hasKey("extra"))
extra = ConfMan.get("extra");
+ }
Common::String gameid = ConfMan.get("gameid");
@@ -305,12 +212,21 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
return Common::kNoGameDataFoundError;
}
- ADGameDescList matches = detectGame(files, params, language, platform, extra);
+ if (files.empty())
+ return Common::kNoGameDataFoundError;
+
+ // Compose a hashmap of all files in fslist.
+ FileMap allFiles;
+ composeFileHashMap(allFiles, files, (_maxScanDepth == 0 ? 1 : _maxScanDepth));
+
+ // Run the detector on this
+ ADGameDescList matches = detectGame(files.begin()->getParent(), allFiles, language, platform, extra);
if (cleanupPirated(matches))
return Common::kNoGameDataFoundError;
- if (params.singleid == NULL) {
+ if (_singleid == NULL) {
+ // Find the first match with correct gameid.
for (uint i = 0; i < matches.size(); i++) {
if (matches[i]->gameid == gameid) {
agdDesc = matches[i];
@@ -323,11 +239,11 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
if (agdDesc == 0) {
// Use fallback detector if there were no matches by other means
- agdDesc = fallbackDetect(files);
+ agdDesc = fallbackDetect(allFiles, files);
if (agdDesc != 0) {
// Seems we found a fallback match. But first perform a basic
// sanity check: the gameid must match.
- if (params.singleid == NULL && agdDesc->gameid != gameid)
+ if (_singleid == NULL && agdDesc->gameid != gameid)
agdDesc = 0;
}
}
@@ -341,10 +257,23 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
if (agdDesc->flags & ADGF_ADDENGLISH)
lang += " " + getGameGUIOptionsDescriptionLanguage(Common::EN_ANY);
- Common::updateGameGUIOptions(agdDesc->guioptions | params.guioptions, lang);
+ Common::updateGameGUIOptions(agdDesc->guioptions | _guioptions, lang);
+
+ GameDescriptor gameDescriptor = toGameDescriptor(*agdDesc, _gameids);
+
+ bool showTestingWarning = false;
+
+#ifdef RELEASE_BUILD
+ showTestingWarning = true;
+#endif
+ if (((gameDescriptor.getSupportLevel() == kUnstableGame
+ || (gameDescriptor.getSupportLevel() == kTestingGame
+ && showTestingWarning)))
+ && !Engine::warnUserAboutUnsupportedGame())
+ return Common::kUserCanceled;
- debug(2, "Running %s", toGameDescriptor(*agdDesc, params.list).description().c_str());
+ debug(2, "Running %s", gameDescriptor.description().c_str());
if (!createInstance(syst, engine, agdDesc))
return Common::kNoGameDataFoundError;
else
@@ -357,7 +286,6 @@ struct SizeMD5 {
};
typedef Common::HashMap<Common::String, SizeMD5, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SizeMD5Map;
-typedef Common::HashMap<Common::String, Common::FSNode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
static void reportUnknown(const Common::FSNode &path, const SizeMD5Map &filesSizeMD5) {
// TODO: This message should be cleaned up / made more specific.
@@ -379,26 +307,22 @@ static void reportUnknown(const Common::FSNode &path, const SizeMD5Map &filesSiz
g_system->logMessage(LogMessageType::kInfo, report.c_str());
}
-static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParams &params);
-
-static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles, int depth, const char * const *directoryGlobs) {
+void AdvancedMetaEngine::composeFileHashMap(FileMap &allFiles, const Common::FSList &fslist, int depth) const {
if (depth <= 0)
return;
if (fslist.empty())
return;
- // First we compose a hashmap of all files in fslist.
- // Includes nifty stuff like removing trailing dots and ignoring case.
for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
if (file->isDirectory()) {
Common::FSList files;
- if (!directoryGlobs)
+ if (!_directoryGlobs)
continue;
bool matched = false;
- for (const char * const *glob = directoryGlobs; *glob; glob++)
+ for (const char * const *glob = _directoryGlobs; *glob; glob++)
if (file->getName().matchString(*glob, true)) {
matched = true;
break;
@@ -410,7 +334,7 @@ static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles,
if (!file->getChildren(files, Common::FSNode::kListAll))
continue;
- composeFileHashMap(files, allFiles, depth - 1, directoryGlobs);
+ composeFileHashMap(allFiles, files, depth - 1);
}
Common::String tstr = file->getName();
@@ -423,26 +347,18 @@ static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles,
}
}
-static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &params, Common::Language language, Common::Platform platform, const Common::String &extra) {
- FileMap allFiles;
+ADGameDescList AdvancedMetaEngine::detectGame(const Common::FSNode &parent, const FileMap &allFiles, Common::Language language, Common::Platform platform, const Common::String &extra) const {
SizeMD5Map filesSizeMD5;
const ADGameFileDescription *fileDesc;
const ADGameDescription *g;
const byte *descPtr;
- if (fslist.empty())
- return ADGameDescList();
- Common::FSNode parent = fslist.begin()->getParent();
debug(3, "Starting detection in dir '%s'", parent.getPath().c_str());
- // First we compose a hashmap of all files in fslist.
- // Includes nifty stuff like removing trailing dots and ignoring case.
- composeFileHashMap(fslist, allFiles, (params.depth == 0 ? 1 : params.depth), params.directoryGlobs);
-
- // Check which files are included in some ADGameDescription *and* present
- // in fslist. Compute MD5s and file sizes for these files.
- for (descPtr = params.descs; ((const ADGameDescription *)descPtr)->gameid != 0; descPtr += params.descItemSize) {
+ // Check which files are included in some ADGameDescription *and* are present.
+ // Compute MD5s and file sizes for these files.
+ for (descPtr = _gameDescriptors; ((const ADGameDescription *)descPtr)->gameid != 0; descPtr += _descItemSize) {
g = (const ADGameDescription *)descPtr;
for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) {
@@ -456,16 +372,14 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
// file and as one with resource fork.
if (g->flags & ADGF_MACRESFORK) {
- Common::MacResManager *macResMan = new Common::MacResManager();
+ Common::MacResManager macResMan;
- if (macResMan->open(parent, fname)) {
- tmp.md5 = macResMan->computeResForkMD5AsString(params.md5Bytes);
- tmp.size = macResMan->getResForkDataSize();
+ if (macResMan.open(parent, fname)) {
+ tmp.md5 = macResMan.computeResForkMD5AsString(_md5Bytes);
+ tmp.size = macResMan.getResForkDataSize();
debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());
filesSizeMD5[fname] = tmp;
}
-
- delete macResMan;
} else {
if (allFiles.contains(fname)) {
debug(3, "+ %s", fname.c_str());
@@ -474,7 +388,7 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
if (testFile.open(allFiles[fname])) {
tmp.size = (int32)testFile.size();
- tmp.md5 = Common::computeStreamMD5AsString(testFile, params.md5Bytes);
+ tmp.md5 = Common::computeStreamMD5AsString(testFile, _md5Bytes);
} else {
tmp.size = -1;
}
@@ -492,7 +406,7 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
// MD5 based matching
uint i;
- for (i = 0, descPtr = params.descs; ((const ADGameDescription *)descPtr)->gameid != 0; descPtr += params.descItemSize, ++i) {
+ for (i = 0, descPtr = _gameDescriptors; ((const ADGameDescription *)descPtr)->gameid != 0; descPtr += _descItemSize, ++i) {
g = (const ADGameDescription *)descPtr;
bool fileMissing = false;
@@ -504,7 +418,7 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
continue;
}
- if ((params.flags & kADFlagUseExtraAsHint) && !extra.empty() && g->extra != extra)
+ if ((_flags & kADFlagUseExtraAsHint) && !extra.empty() && g->extra != extra)
continue;
bool allFilesPresent = true;
@@ -577,28 +491,20 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
}
// Filename based fallback
- if (params.fileBasedFallback != 0)
- matched = detectGameFilebased(allFiles, params);
}
return matched;
}
-/**
- * Check for each ADFileBasedFallback record whether all files listed
- * in it are present. If multiple pass this test, we pick the one with
- * the maximal number of matching files. In case of a tie, the entry
- * coming first in the list is chosen.
- */
-static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParams &params) {
+const ADGameDescription *AdvancedMetaEngine::detectGameFilebased(const FileMap &allFiles, const ADFileBasedFallback *fileBasedFallback) const {
const ADFileBasedFallback *ptr;
const char* const* filenames;
int maxNumMatchedFiles = 0;
const ADGameDescription *matchedDesc = 0;
- for (ptr = params.fileBasedFallback; ptr->desc; ++ptr) {
- const ADGameDescription *agdesc = (const ADGameDescription *)ptr->desc;
+ for (ptr = fileBasedFallback; ptr->desc; ++ptr) {
+ const ADGameDescription *agdesc = ptr->desc;
int numMatchedFiles = 0;
bool fileMissing = false;
@@ -624,28 +530,45 @@ static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParam
}
}
- ADGameDescList matched;
+ return matchedDesc;
+}
+
+GameList AdvancedMetaEngine::getSupportedGames() const {
+ if (_singleid != NULL) {
+ GameList gl;
- if (matchedDesc) { // We got a match
- matched.push_back(matchedDesc);
- if (params.flags & kADFlagPrintWarningOnFileBasedFallback) {
- Common::String report = Common::String::format(_("Your game version has been detected using "
- "filename matching as a variant of %s."), matchedDesc->gameid);
- report += "\n";
- report += _("If this is an original and unmodified version, please report any");
- report += "\n";
- report += _("information previously printed by ScummVM to the team.");
- report += "\n";
- g_system->logMessage(LogMessageType::kInfo, report.c_str());
+ const PlainGameDescriptor *g = _gameids;
+ while (g->gameid) {
+ if (0 == scumm_stricmp(_singleid, g->gameid)) {
+ gl.push_back(GameDescriptor(g->gameid, g->description));
+
+ return gl;
+ }
+ g++;
}
+ error("Engine %s doesn't have its singleid specified in ids list", _singleid);
}
- return matched;
+ return GameList(_gameids);
}
-GameList AdvancedMetaEngine::getSupportedGames() const {
- return gameIDList(params);
-}
GameDescriptor AdvancedMetaEngine::findGame(const char *gameid) const {
- return AdvancedDetector::findGameID(gameid, params.list, params.obsoleteList);
+ // First search the list of supported gameids for a match.
+ const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, _gameids);
+ if (g)
+ return GameDescriptor(*g);
+
+ // No match found
+ return GameDescriptor();
+}
+
+AdvancedMetaEngine::AdvancedMetaEngine(const void *descs, uint descItemSize, const PlainGameDescriptor *gameids)
+ : _gameDescriptors((const byte *)descs), _descItemSize(descItemSize), _gameids(gameids) {
+
+ _md5Bytes = 5000;
+ _singleid = NULL;
+ _flags = 0;
+ _guioptions = Common::GUIO_NONE;
+ _maxScanDepth = 1;
+ _directoryGlobs = NULL;
}
diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h
index 408c46556d..cbdfdf39d8 100644
--- a/engines/advancedDetector.h
+++ b/engines/advancedDetector.h
@@ -19,38 +19,59 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
+
#ifndef ENGINES_ADVANCED_DETECTOR_H
#define ENGINES_ADVANCED_DETECTOR_H
#include "engines/metaengine.h"
+#include "engines/engine.h"
namespace Common {
class Error;
class FSList;
}
-
+/**
+ * A record describing a file to be matched for detecting a specific game
+ * variant. A list of such records is used inside every ADGameDescription to
+ * enable detection.
+ */
struct ADGameFileDescription {
- const char *fileName;
- uint16 fileType; // Optional. Not used during detection, only by engines.
- const char *md5; // Optional. May be NULL.
- int32 fileSize; // Optional. Set to -1 to ignore.
+ const char *fileName; ///< Name of described file.
+ uint16 fileType; ///< Optional. Not used during detection, only by engines.
+ const char *md5; ///< MD5 of (the beginning of) the described file. Optional. Set to NULL to ignore.
+ int32 fileSize; ///< Size of the described file. Set to -1 to ignore.
};
+/**
+ * A shortcut to produce an empty ADGameFileDescription record. Used to mark
+ * the end of a list of these.
+ */
#define AD_LISTEND {NULL, 0, NULL, 0}
+/**
+ * A shortcut to produce a list of ADGameFileDescription records with only one
+ * record that contains just a filename with an MD5, and no file size.
+ */
#define AD_ENTRY1(f, x) {{ f, 0, x, -1}, AD_LISTEND}
+
+/**
+ * A shortcut to produce a list of ADGameFileDescription records with only one
+ * record that contains just a filename with an MD5, plus a file size.
+ */
#define AD_ENTRY1s(f, x, s) {{ f, 0, x, s}, AD_LISTEND}
enum ADGameFlags {
ADGF_NO_FLAGS = 0,
- ADGF_PIRATED = (1 << 23), // flag to designate well known pirated versions with cracks
- 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_CD = (1 << 29), // add "-cd" to gameid
- ADGF_DEMO = (1 << 30) // add "-demo" to gameid
+ ADGF_UNSTABLE = (1 << 21), // flag to designate not yet officially-supported games that are not fit for public testing
+ ADGF_TESTING = (1 << 22), // flag to designate not yet officially-supported games that are fit for public testing
+ ADGF_PIRATED = (1 << 23), ///< flag to designate well known pirated versions with cracks
+ 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_CD = (1 << 29), ///< add "-cd" to gameid
+ ADGF_DEMO = (1 << 30) ///< add "-demo" to gameid
};
struct ADGameDescription {
@@ -71,25 +92,23 @@ struct ADGameDescription {
};
/**
+ * A list of pointers to ADGameDescription structs (or subclasses thereof).
+ */
+typedef Common::Array<const ADGameDescription *> ADGameDescList;
+
+/**
* End marker for a table of ADGameDescription structs. Use this to
* terminate a list to be passed to the AdvancedDetector API.
*/
#define AD_TABLE_END_MARKER \
{ NULL, NULL, { { NULL, 0, NULL, 0 } }, Common::UNK_LANG, Common::kPlatformUnknown, ADGF_NO_FLAGS, Common::GUIO_NONE }
-
-struct ADObsoleteGameID {
- const char *from;
- const char *to;
- Common::Platform platform;
-};
-
struct ADFileBasedFallback {
/**
* Pointer to an ADGameDescription or subclass thereof which will get
* returned if there's a detection match.
*/
- const void *desc;
+ const ADGameDescription *desc;
/**
* A zero-terminated list of filenames used for matching. All files in
@@ -101,149 +120,151 @@ struct ADFileBasedFallback {
enum ADFlags {
/**
- * Warn user about new variant if his version was detected with fallback
- */
- kADFlagPrintWarningOnFileBasedFallback = (1 << 1),
- /**
* Store value of extra field in config file, and use it as a hint
* on subsequent runs. Could be used when there is no way to autodetect
* game (when more than one game sits in same directory), and user picks
* up a variant manually.
+ * In addition, this is useful if two variants of a game sharing the same
+ * gameid are contained in a single directory.
*/
- kADFlagUseExtraAsHint = (1 << 2)
+ kADFlagUseExtraAsHint = (1 << 0)
};
+
/**
- * A structure containing all parameters for the AdvancedDetector.
- * Typically, an engine will have a single instance of this which is
- * used by its AdvancedMetaEngine subclass as a parameter to the
- * primary AdvancedMetaEngine constructor.
+ * A MetaEngine implementation based around the advanced detector code.
*/
-struct ADParams {
+class AdvancedMetaEngine : public MetaEngine {
+protected:
/**
* Pointer to an array of objects which are either ADGameDescription
* or superset structures (i.e. start with an ADGameDescription member.
* The list is terminated by an entry with a gameid equal to 0
* (see AD_TABLE_END_MARKER).
*/
- const byte *descs;
+ const byte *_gameDescriptors;
/**
* The size of a single entry of the above descs array. Always
* must be >= sizeof(ADGameDescription).
*/
- uint descItemSize;
-
- /**
- * The number of bytes to compute MD5 sum for. The AdvancedDetector
- * is primarily based on computing and matching MD5 checksums of files.
- * Since doing that for large files can be slow, it can be restricted
- * to a subset of all files.
- * Typically this will be set to something between 5 and 50 kilobyte,
- * but arbitrary non-zero values are possible.
- */
- uint md5Bytes;
+ const uint _descItemSize;
/**
* A list of all gameids (and their corresponding descriptions) supported
* by this engine.
*/
- const PlainGameDescriptor *list;
+ const PlainGameDescriptor *_gameids;
/**
- * Structure for autoupgrading obsolete targets (optional).
- *
- * @todo Properly explain this.
+ * The number of bytes to compute MD5 sum for. The AdvancedDetector
+ * is primarily based on computing and matching MD5 checksums of files.
+ * Since doing that for large files can be slow, it can be restricted
+ * to a subset of all files.
+ * Typically this will be set to something between 5 and 50 kilobyte,
+ * but arbitrary non-zero values are possible. The default is 5000.
*/
- const ADObsoleteGameID *obsoleteList;
+ uint _md5Bytes;
/**
* Name of single gameid (optional).
*
* @todo Properly explain this -- what does it do?
*/
- const char *singleid;
-
- /**
- * List of files for file-based fallback detection (optional).
- * This is used if the regular MD5 based detection failed to
- * detect anything.
- * As usual this list is terminated by an all-zero entry.
- *
- * @todo Properly explain this
- */
- const ADFileBasedFallback *fileBasedFallback;
+ const char *_singleid;
/**
* A bitmask of flags which can be used to configure the behavior
* of the AdvancedDetector. Refer to ADFlags for a list of flags
* that can be ORed together and passed here.
*/
- uint32 flags;
+ uint32 _flags;
/**
* A bitmask of game GUI options which will be added to each
* entry in addition to per-game options. Refer to GameGUIOption
* enum for the list.
*/
- uint32 guioptions;
+ uint32 _guioptions;
/**
- * Maximum depth of directories to look up
+ * Maximum depth of directories to look up.
* If set to 0, the depth is 1 level
*/
- uint32 depth;
+ uint32 _maxScanDepth;
/**
* Case-insensitive list of directory globs which could be used for
- * going deeper int directory structure.
+ * going deeper into the directory structure.
* @see String::matchString() method for format description.
*
* @note Last item must be 0
*/
- const char * const *directoryGlobs;
-};
-
+ const char * const *_directoryGlobs;
-namespace AdvancedDetector {
-
-/**
- * Scan through the game descriptors specified in params and search for
- * 'gameid' in there. If a match is found, returns a GameDescriptor
- * with gameid and description set.
- */
-GameDescriptor findGameID(
- const char *gameid,
- const PlainGameDescriptor *list,
- const ADObsoleteGameID *obsoleteList = 0
- );
-
-} // End of namespace AdvancedDetector
-
-/**
- * A MetaEngine implementation based around the advanced detector code.
- */
-class AdvancedMetaEngine : public MetaEngine {
- const ADParams &params;
public:
- AdvancedMetaEngine(const ADParams &dp) : params(dp) {}
+ AdvancedMetaEngine(const void *descs, uint descItemSize, const PlainGameDescriptor *gameids);
+ /**
+ * Returns list of targets supported by the engine.
+ * Distinguishes engines with single ID
+ */
virtual GameList getSupportedGames() const;
+
virtual GameDescriptor findGame(const char *gameid) const;
+
virtual GameList detectGames(const Common::FSList &fslist) const;
+
virtual Common::Error createInstance(OSystem *syst, Engine **engine) const;
- // To be provided by subclasses
+protected:
+ // To be implemented by subclasses
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const = 0;
+ typedef Common::HashMap<Common::String, Common::FSNode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
+
/**
* An (optional) generic fallback detect function which is invoked
- * if both the regular MD5 based detection as well as the file
- * based fallback failed to detect anything.
+ * if the regular MD5 based detection failed to detect anything.
*/
- virtual const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const {
+ virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
return 0;
}
+
+protected:
+ /**
+ * Detect games in specified directory.
+ * Parameters language and platform are used to pass on values
+ * specified by the user. This is used to restrict search scope.
+ *
+ * @param allFiles list of all present files, as computed by composeFileHashMap
+ * @param language restrict results to specified language
+ * @param platform restrict results to specified platform
+ * @param extra restrict results to specified extra string (only if kADFlagUseExtraAsHint is set)
+ * @return list of ADGameDescription pointers corresponding to matched games
+ */
+ ADGameDescList detectGame(const Common::FSNode &parent, const FileMap &allFiles, Common::Language language, Common::Platform platform, const Common::String &extra) const;
+
+ /**
+ * Iterates over all ADFileBasedFallback records inside fileBasedFallback.
+ * This then returns the record (or rather, the ADGameDescription
+ * contained in it) for which all files described by it are present, and
+ * among those the one with the maximal number of matching files.
+ * In case of a tie, the entry coming first in the list is chosen.
+ *
+ * @param allFiles a map describing all present files
+ * @param fileBasedFallback a list of ADFileBasedFallback records, zero-terminated
+ */
+ const ADGameDescription *detectGameFilebased(const FileMap &allFiles, const ADFileBasedFallback *fileBasedFallback) const;
+
+ // TODO
+ void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *realDesc) const;
+
+ /**
+ * Compose a hashmap of all files in fslist.
+ * Includes nifty stuff like removing trailing dots and ignoring case.
+ */
+ void composeFileHashMap(FileMap &allFiles, const Common::FSList &fslist, int depth) const;
};
#endif
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 78316588b0..0eefbab04d 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -131,46 +131,65 @@ void AgiEngine::processEvents() {
switch (key = event.kbd.keycode) {
case Common::KEYCODE_LEFT:
case Common::KEYCODE_KP4:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP4)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_LEFT;
break;
case Common::KEYCODE_RIGHT:
case Common::KEYCODE_KP6:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP6)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_RIGHT;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP8)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_UP;
break;
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP2)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN;
break;
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP9)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_UP_RIGHT;
break;
case Common::KEYCODE_PAGEDOWN:
case Common::KEYCODE_KP3:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP3)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN_RIGHT;
break;
case Common::KEYCODE_HOME:
case Common::KEYCODE_KP7:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP7)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_UP_LEFT;
break;
case Common::KEYCODE_END:
case Common::KEYCODE_KP1:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP1)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN_LEFT;
break;
case Common::KEYCODE_KP5:
- key = KEY_STATIONARY;
+ if (_predictiveDialogRunning)
+ key = event.kbd.ascii;
+ else
+ key = KEY_STATIONARY;
break;
case Common::KEYCODE_PLUS:
key = '+';
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 22d8adf92d..a0736d0cc3 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -129,31 +129,6 @@ static const PlainGameDescriptor agiGames[] = {
#include "agi/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Agi::gameDescriptions,
- // Size of that superset structure
- sizeof(Agi::AGIGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- agiGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "agi",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
using namespace Agi;
class AgiMetaEngine : public AdvancedMetaEngine {
@@ -161,7 +136,10 @@ class AgiMetaEngine : public AdvancedMetaEngine {
mutable Common::String _extra;
public:
- AgiMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ AgiMetaEngine() : AdvancedMetaEngine(Agi::gameDescriptions, sizeof(Agi::AGIGameDescription), agiGames) {
+ _singleid = "agi";
+ _guioptions = Common::GUIO_NOSPEECH;
+ }
virtual const char *getName() const {
return "AGI preAGI + v2 + v3";
@@ -177,7 +155,7 @@ public:
virtual void removeSaveState(const char *target, int slot) const;
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
- const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const;
+ const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
};
bool AgiMetaEngine::hasFeature(MetaEngineFeature f) const {
@@ -315,7 +293,7 @@ SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int sl
return SaveStateDescriptor();
}
-const ADGameDescription *AgiMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
+const ADGameDescription *AgiMetaEngine::fallbackDetect(const FileMap &allFilesXXX, const Common::FSList &fslist) const {
typedef Common::HashMap<Common::String, int32> IntMap;
IntMap allFiles;
bool matchedUsingFilenames = false;
@@ -495,7 +473,7 @@ bool AgiBase::canLoadGameStateCurrently() {
bool AgiBase::canSaveGameStateCurrently() {
if (getGameID() == GID_BC) // Technically in Black Cauldron we may save anytime
return true;
-
+
return (!(getGameType() == GType_PreAGI) && getflag(fMenusWork) && !_noSaveLoadAllowed && _game.inputEnabled);
}
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp
index 80e89f410b..edfe83b1cb 100644
--- a/engines/agi/predictive.cpp
+++ b/engines/agi/predictive.cpp
@@ -190,7 +190,7 @@ bool AgiEngine::predictiveDialog() {
bool needRefresh = true;
- for (;;) {
+ while (!shouldQuit()) {
if (needRefresh) {
for (int i = 0; buttons[i]; i++) {
int color1 = colors[i * 2];
@@ -573,8 +573,10 @@ bool AgiEngine::matchWord() {
hi = line - 1;
else if (cmpVal < 0)
lo = line + 1;
- else
+ else {
hi = line;
+ break;
+ }
}
_currentWord.clear();
diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp
index aa338db0f2..f2d7af32da 100644
--- a/engines/agi/sound.cpp
+++ b/engines/agi/sound.cpp
@@ -144,7 +144,7 @@ void SoundMgr::stopSound() {
// not be any harm doing it, so do it anyway.
if (_endflag != -1)
_vm->setflag(_endflag, true);
-
+
_endflag = -1;
}
diff --git a/engines/agi/sound_2gs.cpp b/engines/agi/sound_2gs.cpp
index 3c8a3dfc8d..38e256aa4b 100644
--- a/engines/agi/sound_2gs.cpp
+++ b/engines/agi/sound_2gs.cpp
@@ -167,12 +167,12 @@ uint SoundGen2GS::generateOutput() {
g->seg++;
}
}
-
+
// TODO: Advance vibrato here. The Apple IIGS uses a LFO with
// triangle wave to modulate the frequency of both oscillators.
// In Apple IIGS the vibrato and the envelope are updated at the
// same time, so the vibrato speed depends on ENVELOPE_COEF.
-
+
// Advance oscillators
int s0 = 0;
int s1 = 0;
@@ -202,12 +202,12 @@ uint SoundGen2GS::generateOutput() {
}
}
}
-
+
// Take envelope and MIDI volume information into account.
// Also amplify.
s0 *= vol * g->vel / 127 * 80 / 256;
s1 *= vol * g->vel / 127 * 80 / 256;
-
+
// Select output channel.
if (g->osc[0].chn)
outl += s0;
@@ -375,7 +375,7 @@ void SoundGen2GS::midiNoteOn(int channel, int note, int velocity) {
IIgsGenerator* g = allocateGenerator();
g->ins = _channels[channel].getInstrument();
const IIgsInstrumentHeader* i = g->ins;
-
+
// Pass information from the MIDI channel to the generator. Take
// velocity into account, although simplistically.
velocity *= 5 / 3;
@@ -385,7 +385,7 @@ void SoundGen2GS::midiNoteOn(int channel, int note, int velocity) {
g->key = note;
g->vel = velocity * _channels[channel].getVolume() / 127;
g->chn = channel;
-
+
// Instruments can define different samples to be used based on
// what the key is. Find the correct samples for our key.
int wa = 0;
diff --git a/engines/agi/sound_2gs.h b/engines/agi/sound_2gs.h
index 1a225300ae..9123e18415 100644
--- a/engines/agi/sound_2gs.h
+++ b/engines/agi/sound_2gs.h
@@ -33,7 +33,7 @@ namespace Agi {
// Apple IIGS to halt the corresponding oscillator immediately. We preprocess
// the sample data by converting it to signed values and the instruments by
// detecting prematurely stopping samples beforehand.
-//
+//
// Note: None of the tested SIERRASTANDARD files have zeroes in them. So in
// practice there is no need to check for them. However, they still do exist
// in the sample resources.
@@ -263,7 +263,7 @@ private:
uint _ticks; ///< MIDI ticks (60Hz)
int16 *_out; ///< Output buffer
uint _outSize; ///< Output buffer size
-
+
static const int kSfxMidiChannel = 15; ///< MIDI channel used for playing sample resources
};
diff --git a/engines/agi/sound_midi.cpp b/engines/agi/sound_midi.cpp
index d2c99171e2..0cbaa4af86 100644
--- a/engines/agi/sound_midi.cpp
+++ b/engines/agi/sound_midi.cpp
@@ -33,7 +33,7 @@
// Timing is not perfect, yet. It plays correct, when I use the
// Gravis-Midiplayer, but the songs are too fast when I use playmidi on
// Linux.
-//
+//
// Original program developed by Jens. Christian Restemeier
//
@@ -114,7 +114,7 @@ void SoundGenMIDI::endOfTrack() {
void SoundGenMIDI::play(int resnum) {
MIDISound *track;
-
+
stop();
_isGM = true;
@@ -153,7 +153,7 @@ unsigned char instr[] = {50, 51, 19};
static void writeDelta(Common::MemoryWriteStreamDynamic *st, int32 delta) {
int32 i;
- i = delta >> 21; if (i > 0) st->writeByte((i & 127) | 128);
+ i = delta >> 21; if (i > 0) st->writeByte((i & 127) | 128);
i = delta >> 14; if (i > 0) st->writeByte((i & 127) | 128);
i = delta >> 7; if (i > 0) st->writeByte((i & 127) | 128);
st->writeByte(delta & 127);
@@ -196,7 +196,7 @@ static uint32 convertSND2MIDI(byte *snddata, byte **data) {
int note;
/* I don't know, what frequency equals midi note 0 ... */
/* This moves the song 4 octaves down: */
- fr = (log10(111860.0 / (double)freq) / ll) - 48;
+ fr = (log10(111860.0 / (double)freq) / ll) - 48;
note = (int)floor(fr + 0.5);
if (note < 0) note = 0;
if (note > 127) note = 127;
@@ -222,7 +222,7 @@ static uint32 convertSND2MIDI(byte *snddata, byte **data) {
st.writeByte(0);
st.writeByte(0);
}
- }
+ }
writeDelta(&st, 0);
st.writeByte(0xff);
st.writeByte(0x2f);
diff --git a/engines/agi/sound_pcjr.cpp b/engines/agi/sound_pcjr.cpp
index 319b7049ed..fdebf16b1a 100644
--- a/engines/agi/sound_pcjr.cpp
+++ b/engines/agi/sound_pcjr.cpp
@@ -219,6 +219,7 @@ int SoundGenPCJr::volumeCalc(SndGenChan *chan) {
// return 0 if it's passing more data
// return -1 if it's passing nothing (end of data)
int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
+ ToneChan *tpcm;
SndGenChan *chan;
const byte *data;
@@ -228,6 +229,7 @@ int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
if (!_vm->getflag(fSoundOn))
return -1;
+ tpcm = &_tchannel[ch];
chan = &_channel[ch];
if (!chan->avail)
return -1;
@@ -241,6 +243,9 @@ int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
// if it's 0 then it's not going to be played
// if it's 0xFFFF then the channel data has finished.
if ((chan->duration != 0) && (chan->duration != 0xFFFF)) {
+ tpcm->genTypePrev = -1;
+ tpcm->freqCountPrev = -1;
+
// only tone channels dissolve
if ((ch != 3) && (_dissolveMethod != 0)) // != noise??
chan->dissolveCount = 0;
diff --git a/engines/agi/sound_pcjr.h b/engines/agi/sound_pcjr.h
index f50fd0aa82..4317e86516 100644
--- a/engines/agi/sound_pcjr.h
+++ b/engines/agi/sound_pcjr.h
@@ -45,9 +45,9 @@ struct SndGenChan {
uint16 dissolveCount;
byte attenuation;
byte attenuationCopy;
-
+
GenType genType;
-
+
// for the sample mixer
int freqCount;
};
diff --git a/engines/agi/sound_sarien.cpp b/engines/agi/sound_sarien.cpp
index fc9a57791c..9ea8569b81 100644
--- a/engines/agi/sound_sarien.cpp
+++ b/engines/agi/sound_sarien.cpp
@@ -105,7 +105,7 @@ SoundGenSarien::~SoundGenSarien() {
int SoundGenSarien::readBuffer(int16 *buffer, const int numSamples) {
fillAudio(buffer, numSamples / 2);
-
+
return numSamples;
}
@@ -124,7 +124,7 @@ void SoundGenSarien::play(int resnum) {
for (int i = 0; i < NUM_CHANNELS; i++) {
_chn[i].type = type;
_chn[i].flags = AGI_SOUND_LOOP;
-
+
if (_env) {
_chn[i].flags |= AGI_SOUND_ENVELOPE;
_chn[i].adsr = AGI_SOUND_ENV_ATTACK;
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index fedfd29362..82a2340ad6 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -504,17 +504,16 @@ int AgiEngine::print(const char *p, int lin, int col, int len) {
*
*/
void AgiEngine::printStatus(const char *message, ...) {
- char x[42];
va_list args;
va_start(args, message);
- vsprintf(x, message, args);
+ Common::String x = Common::String::vformat(message, args);
va_end(args);
debugC(4, kDebugLevelText, "fg=%d, bg=%d", STATUS_FG, STATUS_BG);
- printText(x, 0, 0, _game.lineStatus, 40, STATUS_FG, STATUS_BG);
+ printText(x.c_str(), 0, 0, _game.lineStatus, 40, STATUS_FG, STATUS_BG);
}
static void safeStrcat(Common::String &p, const char *t) {
diff --git a/engines/agi/wagparser.cpp b/engines/agi/wagparser.cpp
index 14159c0147..39f9e0dd92 100644
--- a/engines/agi/wagparser.cpp
+++ b/engines/agi/wagparser.cpp
@@ -112,11 +112,11 @@ WagFileParser::~WagFileParser() {
bool WagFileParser::checkAgiVersionProperty(const WagProperty &version) const {
if (version.getCode() == WagProperty::PC_INTVERSION && // Must be AGI interpreter version property
version.getSize() >= 3 && // Need at least three characters for a version number like "X.Y"
- isdigit(version.getData()[0]) && // And the first character must be a digit
+ isdigit(static_cast<unsigned char>(version.getData()[0])) && // And the first character must be a digit
(version.getData()[1] == ',' || version.getData()[1] == '.')) { // And the second a comma or a period
for (int i = 2; i < version.getSize(); i++) // And the rest must all be digits
- if (!isdigit(version.getData()[i]))
+ if (!isdigit(static_cast<unsigned char>(version.getData()[i])))
return false; // Bail out if found a non-digit after the decimal point
return true;
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index eb78ca3d9b..d9a585bd05 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -29,6 +29,7 @@
#include "common/file.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "graphics/cursorman.h"
#include "graphics/palette.h"
@@ -540,10 +541,8 @@ MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name) {
return new MoviePlayerSMK(vm, baseName);
}
- char buf[60];
-
- sprintf(buf, "Cutscene file '%s' not found!", baseName);
- GUI::MessageDialog dialog(buf, "OK");
+ Common::String buf = Common::String::format(_("Cutscene file '%s' not found!"), baseName);
+ GUI::MessageDialog dialog(buf, _("OK"));
dialog.runModal();
return NULL;
diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp
index 629a5d63fc..2be888b92a 100644
--- a/engines/agos/detection.cpp
+++ b/engines/agos/detection.cpp
@@ -23,6 +23,7 @@
#include "base/plugins.h"
#include "engines/advancedDetector.h"
+#include "engines/obsolete.h"
#include "common/config-manager.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -48,7 +49,7 @@ struct AGOSGameDescription {
* corresponding new target and platform combination.
*
*/
-static const ADObsoleteGameID obsoleteGameIDsTable[] = {
+static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = {
{"simon1acorn", "simon1", Common::kPlatformAcorn},
{"simon1amiga", "simon1", Common::kPlatformAmiga},
{"simon1cd32", "simon1", Common::kPlatformAmiga},
@@ -63,7 +64,7 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
{0, 0, Common::kPlatformUnknown}
};
-static const PlainGameDescriptor simonGames[] = {
+static const PlainGameDescriptor agosGames[] = {
{"pn", "Personal Nightmare"},
{"elvira1", "Elvira - Mistress of the Dark"},
{"elvira2", "Elvira II - The Jaws of Cerberus"},
@@ -87,36 +88,19 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)AGOS::gameDescriptions,
- // Size of that superset structure
- sizeof(AGOS::AGOSGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- simonGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
using namespace AGOS;
class AgosMetaEngine : public AdvancedMetaEngine {
public:
- AgosMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ AgosMetaEngine() : AdvancedMetaEngine(AGOS::gameDescriptions, sizeof(AGOS::AGOSGameDescription), agosGames) {
+ _guioptions = Common::GUIO_NOLAUNCHLOAD;
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ }
+
+ virtual GameDescriptor findGame(const char *gameid) const {
+ return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable);
+ }
virtual const char *getName() const {
return "AGOS";
@@ -127,7 +111,13 @@ public:
}
virtual bool hasFeature(MetaEngineFeature f) const;
+
+ virtual Common::Error createInstance(OSystem *syst, Engine **engine) const {
+ Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable);
+ return AdvancedMetaEngine::createInstance(syst, engine);
+ }
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+
virtual SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
};
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index bde59b71b8..3bd8ce19a3 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -465,8 +465,8 @@ void AGOSEngine_PN::opn_opcode35() {
void AGOSEngine_PN::opn_opcode36() {
for (int i = 0; i < _dataBase[57] + 1; ++i)
_wordcp[i] = 0;
- if (isspace(*_inpp))
- while ((*_inpp) && (isspace(*_inpp)))
+ if (isspace(static_cast<unsigned char>(*_inpp)))
+ while ((*_inpp) && (isspace(static_cast<unsigned char>(*_inpp))))
_inpp++;
if (*_inpp == 0) {
setScriptReturn(false);
@@ -480,7 +480,7 @@ void AGOSEngine_PN::opn_opcode36() {
}
int ct = 1;
- while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(*_inpp)) && (*_inpp != '\0') &&
+ while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(static_cast<unsigned char>(*_inpp))) && (*_inpp != '\0') &&
(*_inpp!='"')) {
if (ct < _dataBase[57])
_wordcp[ct++] = *_inpp;
@@ -580,7 +580,7 @@ void AGOSEngine_PN::opn_opcode46() {
return;
}
x++;
- while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(*x)) && (*x != '\0'))
+ while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(static_cast<unsigned char>(*x))) && (*x != '\0'))
pcf(*x++);
setScriptReturn(true);
}
diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index 1cdd7f6d81..410fd5a1ce 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -517,8 +517,7 @@ void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *strin
y -= textHeight;
} else
pos = stringLength;
- padding = (lettersPerRow - pos) % 2 ?
- (lettersPerRow - pos) / 2 + 1 : (lettersPerRow - pos) / 2;
+ padding = ((lettersPerRow - pos) % 2) ? (lettersPerRow - pos) / 2 + 1 : (lettersPerRow - pos) / 2;
while (padding--)
*convertedString2++ = ' ';
stringLength -= pos;
@@ -621,7 +620,7 @@ void AGOSEngine_PuzzlePack::printInfoText(const char *itemText) {
itemName = " Gem: ";
}
break;
-
+
case 82:
if (_variableArray[flag]) {
if (_variableArray[flag] == 201 || _variableArray[flag] == 211)
@@ -723,11 +722,9 @@ void AGOSEngine_Feeble::printScreenText(uint vgaSpriteId, uint color, const char
const char *string2 = string;
int16 height, talkDelay;
int stringLength = strlen(string);
- int lettersPerRow;
const int textHeight = 15;
height = textHeight;
- lettersPerRow = width / 6;
talkDelay = (stringLength + 3) / 3;
if (_variableArray[86] == 0)
@@ -840,13 +837,12 @@ void AGOSEngine_Feeble::printInteractText(uint16 num, const char *string) {
void AGOSEngine_Feeble::sendInteractText(uint16 num, const char *fmt, ...) {
va_list arglist;
- char string[256];
va_start(arglist, fmt);
- vsprintf(string, fmt, arglist);
+ Common::String string = Common::String::vformat(fmt, arglist);
va_end(arglist);
- printInteractText(num, string);
+ printInteractText(num, string.c_str());
}
#endif
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index 738366124c..ba0251520b 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -23,6 +23,7 @@
#include "base/plugins.h"
#include "engines/advancedDetector.h"
+#include "engines/obsolete.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -52,7 +53,7 @@ static const PlainGameDescriptor cineGames[] = {
{0, 0}
};
-static const ADObsoleteGameID obsoleteGameIDsTable[] = {
+static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = {
{"fw", "cine", Common::kPlatformUnknown},
{"os", "cine", Common::kPlatformUnknown},
{0, 0, Common::kPlatformUnknown}
@@ -60,34 +61,16 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
#include "cine/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Cine::gameDescriptions,
- // Size of that superset structure
- sizeof(Cine::CINEGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- cineGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- "cine",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class CineMetaEngine : public AdvancedMetaEngine {
public:
- CineMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ CineMetaEngine() : AdvancedMetaEngine(Cine::gameDescriptions, sizeof(Cine::CINEGameDescription), cineGames) {
+ _singleid = "cine";
+ _guioptions = Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI;
+ }
+
+ virtual GameDescriptor findGame(const char *gameid) const {
+ return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable);
+ }
virtual const char *getName() const {
return "Cine";
@@ -97,7 +80,12 @@ public:
return "Future Wars & Operation Stealth (C) Delphine Software";
}
+ virtual Common::Error createInstance(OSystem *syst, Engine **engine) const {
+ Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable);
+ return AdvancedMetaEngine::createInstance(syst, engine);
+ }
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+
virtual bool hasFeature(MetaEngineFeature f) const;
virtual SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
@@ -153,7 +141,7 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
for (file = filenames.begin(); file != filenames.end(); ++file) {
// Jump over savegame files that don't end with a digit (e.g. "fw.3" is ok, "fw.a" is not).
- if (!isdigit(file->lastChar()))
+ if (!isdigit(static_cast<unsigned char>(file->lastChar())))
continue;
// Obtain the last digit of the filename, since they correspond to the save slot
diff --git a/engines/cine/prc.cpp b/engines/cine/prc.cpp
index d86107a8f8..ba9ba70110 100644
--- a/engines/cine/prc.cpp
+++ b/engines/cine/prc.cpp
@@ -98,10 +98,10 @@ bool loadPrc(const char *pPrcName) {
char buffer[256];
for (s = 0; s < numScripts; s++) {
- if (scriptTable[s]->_size) {
+ if (g_cine->_scriptTable[s]->_size) {
sprintf(buffer, "%s_%03d.txt", pPrcName, s);
- decompileScript((const byte *)scriptTable[s]->getString(0), scriptTable[s]->_size, s);
+ decompileScript((const byte *)g_cine->_scriptTable[s]->getString(0), g_cine->_scriptTable[s]->_size, s);
dumpScript(buffer);
}
}
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 81e72d6905..cdb5140002 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -55,7 +55,7 @@ int16 canUseOnObject = 0;
void waitPlayerInput() {
uint16 button;
-
+
do {
manageEvents();
getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16);
diff --git a/engines/cruise/background.cpp b/engines/cruise/background.cpp
index 1e7e87cf38..4d1284a802 100644
--- a/engines/cruise/background.cpp
+++ b/engines/cruise/background.cpp
@@ -212,7 +212,7 @@ int loadBackground(const char *name, int idx) {
// NOTE: the following is really meant to compare pointers and not the actual
// strings. See r48092 and r48094.
if (name != backgroundTable[idx].name) {
- if (strlen(name) >= sizeof(backgroundTable[idx].name))
+ if (strlen(name) >= sizeof(backgroundTable[idx].name))
warning("background name length exceeded allowable maximum");
Common::strlcpy(backgroundTable[idx].name, name, sizeof(backgroundTable[idx].name));
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index 3f13c6cbff..a97583c972 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -1882,7 +1882,7 @@ void CruiseEngine::mainLoop() {
while (numIterations-- > 0) {
bgChanged = backgroundChanged[masterScreen];
-
+
manageScripts(&relHead);
manageScripts(&procHead);
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index 3bd0c1f76f..5be2fdeeea 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -217,34 +217,12 @@ static const CRUISEGameDescription gameDescriptions[] = {
}
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Cruise::gameDescriptions,
- // Size of that superset structure
- sizeof(Cruise::CRUISEGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- cruiseGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "cruise",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class CruiseMetaEngine : public AdvancedMetaEngine {
public:
- CruiseMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ CruiseMetaEngine() : AdvancedMetaEngine(Cruise::gameDescriptions, sizeof(Cruise::CRUISEGameDescription), cruiseGames) {
+ _singleid = "cruise";
+ _guioptions = Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI;
+ }
virtual const char *getName() const {
return "CruisE";
diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp
index 3fd8671e55..1a077e5bf7 100644
--- a/engines/dialogs.cpp
+++ b/engines/dialogs.cpp
@@ -143,9 +143,9 @@ void MainMenuDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint3
break;
case kHelpCmd: {
GUI::MessageDialog dialog(
- "Sorry, this engine does not currently provide in-game help. "
+ _("Sorry, this engine does not currently provide in-game help. "
"Please consult the README for basic information, and for "
- "instructions on how to obtain further assistance.");
+ "instructions on how to obtain further assistance."));
dialog.runModal();
}
break;
@@ -173,7 +173,7 @@ void MainMenuDialog::reflowLayout() {
_loadButton->setEnabled(_engine->canLoadGameStateCurrently());
if (_engine->hasFeature(Engine::kSupportsSavingDuringRuntime))
_saveButton->setEnabled(_engine->canSaveGameStateCurrently());
-
+
// Overlay size might have changed since the construction of the dialog.
// Update labels when it might be needed
// FIXME: it might be better to declare GUI::StaticTextWidget::setLabel() virtual
@@ -246,14 +246,10 @@ void MainMenuDialog::load() {
int slot = _loadDialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
- if (slot >= 0) {
- // FIXME: For now we just ignore the return
- // value, which is quite bad since it could
- // be a fatal loading error, which renders
- // the engine unusable.
- _engine->loadGameState(slot);
+ _engine->setGameToLoadSlot(slot);
+
+ if (slot >= 0)
close();
- }
}
enum {
diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp
index d3483eb5a4..b7e83e1edb 100644
--- a/engines/draci/detection.cpp
+++ b/engines/draci/detection.cpp
@@ -83,34 +83,11 @@ const ADGameDescription gameDescriptions[] = {
} // End of namespace Draci
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Draci::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- draciGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "draci",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class DraciMetaEngine : public AdvancedMetaEngine {
public:
- DraciMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ DraciMetaEngine() : AdvancedMetaEngine(Draci::gameDescriptions, sizeof(ADGameDescription), draciGames) {
+ _singleid = "draci";
+ }
virtual const char *getName() const {
return "Draci";
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp
index c4df9d9dde..8ff60033ed 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -1160,9 +1160,7 @@ void Script::run(const GPL2Program &program, uint16 offset) {
}
}
} else {
- debugC(1, kDraciBytecodeDebugLevel, "Unknown opcode %d, %d",
- num, subnum);
- abort();
+ error("Unknown opcode %d, %d", num, subnum);
}
GPLHandler handler = cmd->_handler;
diff --git a/engines/draci/sound.cpp b/engines/draci/sound.cpp
index 106167ef8a..d534f46a6e 100644
--- a/engines/draci/sound.cpp
+++ b/engines/draci/sound.cpp
@@ -67,8 +67,12 @@ void LegacySoundArchive::openArchive(const char *path) {
debugC(1, kDraciArchiverDebugLevel, "Loading header");
uint totalLength = _f->readUint32LE();
+
const uint kMaxSamples = 4095; // The no-sound file is exactly 16K bytes long, so don't fail on short reads
- uint sampleStarts[kMaxSamples];
+ uint *sampleStarts = (uint *)malloc(kMaxSamples * sizeof(uint));
+ if (!sampleStarts)
+ error("[LegacySoundArchive::openArchive] Cannot allocate buffer for no-sound file");
+
for (uint i = 0; i < kMaxSamples; ++i) {
sampleStarts[i] = _f->readUint32LE();
}
@@ -90,17 +94,22 @@ void LegacySoundArchive::openArchive(const char *path) {
}
if (_samples[_sampleCount-1]._offset + _samples[_sampleCount-1]._length != totalLength &&
_samples[_sampleCount-1]._offset + _samples[_sampleCount-1]._length - _samples[0]._offset != totalLength) {
- // WORKAROUND: the stored length is stored with the header for sounds and without the hader for dubbing. Crazy.
+ // WORKAROUND: the stored length is stored with the header for sounds and without the header for dubbing. Crazy.
debugC(1, kDraciArchiverDebugLevel, "Broken sound archive: %d != %d",
_samples[_sampleCount-1]._offset + _samples[_sampleCount-1]._length,
totalLength);
closeArchive();
+
+ free(sampleStarts);
+
return;
}
} else {
debugC(1, kDraciArchiverDebugLevel, "Archive info: empty");
}
+ free(sampleStarts);
+
// Indicate that the archive has been successfully opened
_opened = true;
}
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 5a8903db9d..6ba5597e8a 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -243,7 +243,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
GUIO_NONE
},
},
-
+
{
// Drascula French version (ScummVM repacked files)
{
@@ -266,34 +266,12 @@ static const DrasculaGameDescription gameDescriptions[] = {
} // End of namespace Drascula
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Drascula::gameDescriptions,
- // Size of that superset structure
- sizeof(Drascula::DrasculaGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- drasculaGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "drascula",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class DrasculaMetaEngine : public AdvancedMetaEngine {
public:
- DrasculaMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ DrasculaMetaEngine() : AdvancedMetaEngine(Drascula::gameDescriptions, sizeof(Drascula::DrasculaGameDescription), drasculaGames) {
+ _singleid = "drascula";
+ _guioptions = Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD;
+ }
virtual const char *getName() const {
return "Drascula";
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index d133b3609d..9ea20e3e12 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -204,7 +204,7 @@ void DrasculaEngine::copyRect(int xorg, int yorg, int xdes, int ydes, int width,
}
ptr += 320 - width;
}
-
+
}
void DrasculaEngine::updateScreen(int xorg, int yorg, int xdes, int ydes, int width, int height, byte *buffer) {
@@ -354,7 +354,7 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
print_abc(msg, x, y);
return;
}
-
+
// Message doesn't fit on screen, split it
// Get a word from the message
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index eb36baed18..e3a97087c0 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -159,7 +159,7 @@ void DrasculaEngine::enterName() {
key = getScan();
if (key != 0) {
- if (key >= 0 && key <= 0xFF && isalpha(key))
+ if (key >= 0 && key <= 0xFF && isalpha(static_cast<unsigned char>(key)))
select2[v] = tolower(key);
else if ((key >= Common::KEYCODE_0 && key <= Common::KEYCODE_9) || key == Common::KEYCODE_SPACE)
select2[v] = key;
diff --git a/engines/drascula/resource.cpp b/engines/drascula/resource.cpp
index bda25113b7..6da43e7cba 100644
--- a/engines/drascula/resource.cpp
+++ b/engines/drascula/resource.cpp
@@ -45,7 +45,7 @@ TextResourceParser::TextResourceParser(Common::SeekableReadStream *stream, Dispo
_stream(stream), _dispose(dispose) {
// NOTE: strangely enough, the code before this refactoring used the size of
- // the stream as a fixed maximum length for the parser. Using an updated
+ // the stream as a fixed maximum length for the parser. Using an updated
// (size-pos) would make more sense to me, but let's see what the experts say.
_maxLen = _stream->size();
}
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index 50d44bab79..9f725b6d76 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1675,7 +1675,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
if (!stream) {
error("missing data file %s", fileName);
}
-
+
TextResourceParser p(stream, DisposeAfterUse::YES);
p.parseInt(roomNumber);
diff --git a/engines/dreamweb/README b/engines/dreamweb/README
new file mode 100644
index 0000000000..d184613249
--- /dev/null
+++ b/engines/dreamweb/README
@@ -0,0 +1,12 @@
+
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+
+Some files(dreamgen.*) in this directory is auto-generated. This means
+(at least for some time) any changes to them will be lost.
+
+Please look into /devtools/tasmrecover directory, patch assembler source
+or translator and run ./tasm-recover script.
+
+Then copy dreamgen.cpp/dreamgen.h to engine/dreamweb and check the diffs.
+
+If you'd like to reimplement something, blacklist it, then run script.
diff --git a/engines/dreamweb/console.cpp b/engines/dreamweb/console.cpp
new file mode 100644
index 0000000000..e004746d8a
--- /dev/null
+++ b/engines/dreamweb/console.cpp
@@ -0,0 +1,36 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://svn.scummvm.org:4444/svn/dreamweb/console.cpp $
+ * $Id: console.cpp 70 2011-01-26 05:36:55Z digitall $
+ *
+ */
+
+#include "dreamweb/console.h"
+
+namespace DreamWeb {
+
+DreamWebConsole::DreamWebConsole(DreamWebEngine *vm) : GUI::Debugger(), _vm(vm) {
+}
+
+DreamWebConsole::~DreamWebConsole() {
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/console.h b/engines/dreamweb/console.h
new file mode 100644
index 0000000000..58c8467b34
--- /dev/null
+++ b/engines/dreamweb/console.h
@@ -0,0 +1,46 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://svn.scummvm.org:4444/svn/dreamweb/console.h $
+ * $Id: console.h 70 2011-01-26 05:36:55Z digitall $
+ *
+ */
+
+#ifndef DREAMWEB_CONSOLE_H
+#define DREAMWEB_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace DreamWeb {
+
+class DreamWebEngine;
+
+class DreamWebConsole : public GUI::Debugger {
+public:
+ DreamWebConsole(DreamWebEngine *vm);
+ virtual ~DreamWebConsole(void);
+
+private:
+ DreamWebEngine *_vm;
+};
+
+} // End of namespace DreamWeb
+
+#endif
diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp
new file mode 100644
index 0000000000..d32be6a2b7
--- /dev/null
+++ b/engines/dreamweb/detection.cpp
@@ -0,0 +1,147 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://svn.scummvm.org:4444/svn/dreamweb/detection.cpp $
+ * $Id: detection.cpp 3 2010-09-16 19:32:18Z megath $
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "common/algorithm.h"
+#include "common/system.h"
+
+#include "dreamweb/dreamweb.h"
+
+static const PlainGameDescriptor dreamWebGames[] = {
+ { "dreamweb", "DreamWeb" },
+ { 0, 0 }
+};
+
+#include "dreamweb/detection_tables.h"
+
+class DreamWebMetaEngine : public AdvancedMetaEngine {
+public:
+ DreamWebMetaEngine():
+ AdvancedMetaEngine(DreamWeb::gameDescriptions,
+ sizeof(DreamWeb::DreamWebGameDescription), dreamWebGames) {
+ _singleid = "dreamweb";
+ _guioptions = Common::GUIO_NOMIDI;
+ }
+
+ virtual const char *getName() const {
+ return "DreamWeb engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "DreamWeb (C) Creative Reality";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual SaveStateList listSaves(const char *target) const;
+ virtual int getMaximumSaveSlot() const;
+ virtual void removeSaveState(const char *target, int slot) const;
+};
+
+bool DreamWebMetaEngine::hasFeature(MetaEngineFeature f) const {
+ switch(f) {
+ case kSupportsListSaves:
+ //case kSupportsLoadingDuringStartup:
+ //case kSupportsDeleteSave:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool DreamWeb::DreamWebEngine::hasFeature(EngineFeature f) const {
+ switch(f) {
+ case kSupportsRTL:
+ return true;
+ case kSupportsSubtitleOptions:
+ return _gameDescription->desc.flags & ADGF_CD;
+ default:
+ return false;
+ }
+ return false;
+}
+
+bool DreamWebMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ const DreamWeb::DreamWebGameDescription *gd = (const DreamWeb::DreamWebGameDescription *)desc;
+ if (gd) {
+ *engine = new DreamWeb::DreamWebEngine(syst, gd);
+ }
+ return gd != 0;
+}
+
+SaveStateList DreamWebMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray files = saveFileMan->listSavefiles("DREAMWEB.D??");
+ Common::sort(files.begin(), files.end());
+
+ SaveStateList saveList;
+ for(uint i = 0; i < files.size(); ++i) {
+ const Common::String &file = files[i];
+ Common::InSaveFile *stream = saveFileMan->openForLoading(file);
+ if (!stream)
+ error("cannot open save file %s", file.c_str());
+ char name[17] = {};
+ stream->seek(0x61);
+ stream->read(name, sizeof(name) - 1);
+ delete stream;
+
+ SaveStateDescriptor sd(i, name);
+ saveList.push_back(sd);
+ }
+
+ return saveList;
+}
+
+int DreamWebMetaEngine::getMaximumSaveSlot() const { return 6; }
+
+void DreamWebMetaEngine::removeSaveState(const char *target, int slot) const {
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(DREAMWEB)
+ REGISTER_PLUGIN_DYNAMIC(DREAMWEB, PLUGIN_TYPE_ENGINE, DreamWebMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(DREAMWEB, PLUGIN_TYPE_ENGINE, DreamWebMetaEngine);
+#endif
+
+namespace DreamWeb {
+
+Common::Error DreamWebEngine::loadGameState(int slot) {
+ return Common::kNoError;
+}
+
+Common::Error DreamWebEngine::saveGameState(int slot, const Common::String &desc) {
+ return Common::kNoError;
+}
+
+bool DreamWebEngine::canLoadGameStateCurrently() {
+ return false;
+}
+
+bool DreamWebEngine::canSaveGameStateCurrently() {
+ return false;
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/detection_tables.h b/engines/dreamweb/detection_tables.h
new file mode 100644
index 0000000000..0449361a98
--- /dev/null
+++ b/engines/dreamweb/detection_tables.h
@@ -0,0 +1,157 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://svn.scummvm.org:4444/svn/dreamweb/detection_tables.h $
+ * $Id: detection_tables.h 66 2010-11-07 08:31:21Z eriktorbjorn $
+ *
+ */
+
+#ifndef DREAMWEB_DETECTION_TABLES_H
+#define DREAMWEB_DETECTION_TABLES_H
+
+namespace DreamWeb {
+
+using Common::GUIO_NONE;
+
+static const DreamWebGameDescription gameDescriptions[] = {
+ {
+ {
+ "dreamweb",
+ "",
+ {
+ {"dreamweb.r00", 0, "3b5c87717fc40cc5a5ae19c155662ee3", 152918},
+ {"dreamweb.r02", 0, "28458718167a040d7e988cf7d2298eae", 210466},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_UNSTABLE,
+ GUIO_NONE
+ },
+ },
+
+ // International CD release
+ {
+ {
+ "dreamweb",
+ "CD",
+ {
+ {"dreamweb.r00", 0, "3b5c87717fc40cc5a5ae19c155662ee3", 152918},
+ {"dreamweb.r02", 0, "d6fe5e3590ec1eea42ff65c10b023e0f", 198681},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_CD | ADGF_UNSTABLE,
+ GUIO_NONE
+ },
+ },
+
+ // US CD release
+ {
+ {
+ "dreamweb",
+ "CD",
+ {
+ {"dreamweb.r00", 0, "8acafd7f4418d08d0e16b65b8b10bc50", 152983},
+ {"dreamweb.r02", 0, "c0c363715ddf14ab54f2379906a3aa01", 198707},
+ AD_LISTEND
+ },
+ Common::EN_USA,
+ Common::kPlatformPC,
+ ADGF_CD,
+ GUIO_NONE
+ },
+ },
+
+ // German floppy release
+ {
+ {
+ "dreamweb",
+ "",
+ {
+ {"dreamweb.r00", 0, "9960dc3baddabc6ad2a6fd75292b149c", 155886},
+ {"dreamweb.r02", 0, "48e1f42a53402f963ca2d1ed969f4084", 212823},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_UNSTABLE,
+ GUIO_NONE
+ },
+ },
+
+ // German CD release
+ {
+ {
+ "dreamweb",
+ "CD",
+ {
+ {"dreamweb.r00", 0, "9960dc3baddabc6ad2a6fd75292b149c", 155886},
+ {"dreamweb.r02", 0, "076ca7cd326cb2abfb2091c6cf46ae08", 201038},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_CD | ADGF_UNSTABLE,
+ GUIO_NONE
+ },
+ },
+
+ // Spanish floppy release
+ {
+ {
+ "dreamweb",
+ "",
+ {
+ {"dreamweb.r00", 0, "2df07174321de39c4f17c9ff654b268a", 153608},
+ {"dreamweb.r02", 0, "f97d435ad5da08fb1bcf6ea3dd6e0b9e", 199499},
+ AD_LISTEND
+ },
+ Common::ES_ESP,
+ Common::kPlatformPC,
+ ADGF_UNSTABLE,
+ GUIO_NONE
+ },
+ },
+
+ // Italian floppy release
+ {
+ {
+ "dreamweb",
+ "",
+ {
+ {"dreamweb.r00", 0, "66dcab08354232f423c590156335f819", 155448},
+ {"dreamweb.r02", 0, "87a026e9f80ed4f94169381f871ee305", 199676},
+ AD_LISTEND
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ ADGF_UNSTABLE,
+ GUIO_NONE
+ },
+ },
+
+ { AD_TABLE_END_MARKER }
+};
+
+} // End of namespace DreamWeb
+
+#endif
diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp
new file mode 100644
index 0000000000..a183c7c798
--- /dev/null
+++ b/engines/dreamweb/dreamgen.cpp
@@ -0,0 +1,22821 @@
+/* PLEASE DO NOT MODIFY THIS FILE. ALL CHANGES WILL BE LOST! LOOK FOR README FOR DETAILS */
+
+#include "dreamgen.h"
+
+namespace DreamGen {
+
+void DreamGenContext::alleybarksound() {
+ STACK_CHECK;
+ ax = es.word(bx+3);
+ _dec(ax);
+ _cmp(ax, 0);
+ if (!flags.z())
+ goto nobark;
+ push(bx);
+ push(es);
+ al = 14;
+ playchannel1();
+ es = pop();
+ bx = pop();
+ ax = 1000;
+nobark:
+ es.word(bx+3) = ax;
+}
+
+void DreamGenContext::intromusic() {
+ STACK_CHECK;
+}
+
+void DreamGenContext::foghornsound() {
+ STACK_CHECK;
+ randomnumber();
+ _cmp(al, 198);
+ if (!flags.z())
+ return /* (nofog) */;
+ al = 13;
+ playchannel1();
+}
+
+void DreamGenContext::receptionist() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto gotrecep;
+ _cmp(data.byte(kCardpassflag), 1);
+ if (!flags.z())
+ goto notsetcard;
+ _inc(data.byte(kCardpassflag));
+ es.byte(bx+7) = 1;
+ es.word(bx+3) = 64;
+notsetcard:
+ _cmp(es.word(bx+3), 58);
+ if (!flags.z())
+ goto notdes1;
+ randomnumber();
+ _cmp(al, 30);
+ if (flags.c())
+ goto notdes2;
+ es.word(bx+3) = 55;
+ goto gotrecep;
+notdes1:
+ _cmp(es.word(bx+3), 60);
+ if (!flags.z())
+ goto notdes2;
+ randomnumber();
+ _cmp(al, 240);
+ if (flags.c())
+ goto gotrecep;
+ es.word(bx+3) = 53;
+ goto gotrecep;
+notdes2:
+ _cmp(es.word(bx+3), 88);
+ if (!flags.z())
+ goto notendcard;
+ es.word(bx+3) = 53;
+ goto gotrecep;
+notendcard:
+ _inc(es.word(bx+3));
+gotrecep:
+ showgamereel();
+ addtopeoplelist();
+ al = es.byte(bx+7);
+ _and(al, 128);
+ if (flags.z())
+ return /* (nottalkedrecep) */;
+ data.byte(kTalkedtorecep) = 1;
+}
+
+void DreamGenContext::smokebloke() {
+ STACK_CHECK;
+ _cmp(data.byte(kRockstardead), 0);
+ if (!flags.z())
+ goto notspokento;
+ al = es.byte(bx+7);
+ _and(al, 128);
+ if (flags.z())
+ goto notspokento;
+ push(es);
+ push(bx);
+ al = 5;
+ setlocation();
+ bx = pop();
+ es = pop();
+notspokento:
+ checkspeed();
+ if (!flags.z())
+ goto gotsmokeb;
+ _cmp(es.word(bx+3), 100);
+ if (!flags.z())
+ goto notsmokeb1;
+ randomnumber();
+ _cmp(al, 30);
+ if (flags.c())
+ goto notsmokeb2;
+ es.word(bx+3) = 96;
+ goto gotsmokeb;
+notsmokeb1:
+ _cmp(es.word(bx+3), 117);
+ if (!flags.z())
+ goto notsmokeb2;
+ es.word(bx+3) = 96;
+ goto gotsmokeb;
+notsmokeb2:
+ _inc(es.word(bx+3));
+gotsmokeb:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::attendant() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+ al = es.byte(bx+7);
+ _and(al, 128);
+ if (flags.z())
+ return /* (nottalked) */;
+ data.byte(kTalkedtoattendant) = 1;
+}
+
+void DreamGenContext::manasleep() {
+ STACK_CHECK;
+ al = es.byte(bx+7);
+ _and(al, 127);
+ es.byte(bx+7) = al;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::eden() {
+ STACK_CHECK;
+ _cmp(data.byte(kGeneraldead), 0);
+ if (!flags.z())
+ return /* (notinbed) */;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::edeninbath() {
+ STACK_CHECK;
+ _cmp(data.byte(kGeneraldead), 0);
+ if (flags.z())
+ return /* (notinbath) */;
+ _cmp(data.byte(kSartaindead), 0);
+ if (!flags.z())
+ return /* (notinbath) */;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::malefan() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::femalefan() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::louis() {
+ STACK_CHECK;
+ _cmp(data.byte(kRockstardead), 0);
+ if (!flags.z())
+ return /* (notlouis1) */;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::louischair() {
+ STACK_CHECK;
+ _cmp(data.byte(kRockstardead), 0);
+ if (flags.z())
+ return /* (notlouis2) */;
+ checkspeed();
+ if (!flags.z())
+ goto notlouisanim;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 191);
+ if (flags.z())
+ goto restartlouis;
+ _cmp(ax, 185);
+ if (flags.z())
+ goto randomlouis;
+ es.word(bx+3) = ax;
+ goto notlouisanim;
+randomlouis:
+ es.word(bx+3) = ax;
+ randomnumber();
+ _cmp(al, 245);
+ if (!flags.c())
+ goto notlouisanim;
+restartlouis:
+ ax = 182;
+ es.word(bx+3) = ax;
+notlouisanim:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::manasleep2() {
+ STACK_CHECK;
+ al = es.byte(bx+7);
+ _and(al, 127);
+ es.byte(bx+7) = al;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::mansatstill() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::tattooman() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::drinker() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto gotdrinker;
+ _inc(es.word(bx+3));
+ _cmp(es.word(bx+3), 115);
+ if (!flags.z())
+ goto notdrinker1;
+ es.word(bx+3) = 105;
+ goto gotdrinker;
+notdrinker1:
+ _cmp(es.word(bx+3), 106);
+ if (!flags.z())
+ goto gotdrinker;
+ randomnumber();
+ _cmp(al, 3);
+ if (flags.c())
+ goto gotdrinker;
+ es.word(bx+3) = 105;
+gotdrinker:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::bartender() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto gotsmoket;
+ _cmp(es.word(bx+3), 86);
+ if (!flags.z())
+ goto notsmoket1;
+ randomnumber();
+ _cmp(al, 18);
+ if (flags.c())
+ goto notsmoket2;
+ es.word(bx+3) = 81;
+ goto gotsmoket;
+notsmoket1:
+ _cmp(es.word(bx+3), 103);
+ if (!flags.z())
+ goto notsmoket2;
+ es.word(bx+3) = 81;
+ goto gotsmoket;
+notsmoket2:
+ _inc(es.word(bx+3));
+gotsmoket:
+ showgamereel();
+ _cmp(data.byte(kGunpassflag), 1);
+ if (!flags.z())
+ goto notgotgun;
+ es.byte(bx+7) = 9;
+notgotgun:
+ addtopeoplelist();
+}
+
+void DreamGenContext::othersmoker() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::barwoman() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::interviewer() {
+ STACK_CHECK;
+ _cmp(data.word(kReeltowatch), 68);
+ if (!flags.z())
+ goto notgeneralstart;
+ _inc(es.word(bx+3));
+notgeneralstart:
+ _cmp(es.word(bx+3), 250);
+ if (flags.z())
+ goto talking;
+ checkspeed();
+ if (!flags.z())
+ goto talking;
+ _cmp(es.word(bx+3), 259);
+ if (flags.z())
+ goto talking;
+ _inc(es.word(bx+3));
+talking:
+ showgamereel();
+}
+
+void DreamGenContext::soldier1() {
+ STACK_CHECK;
+ _cmp(es.word(bx+3), 0);
+ if (flags.z())
+ goto soldierwait;
+ data.word(kWatchingtime) = 10;
+ _cmp(es.word(bx+3), 30);
+ if (!flags.z())
+ goto notaftersshot;
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 40);
+ if (!flags.z())
+ goto gotsoldframe;
+ data.byte(kMandead) = 2;
+ goto gotsoldframe;
+notaftersshot:
+ checkspeed();
+ if (!flags.z())
+ goto gotsoldframe;
+ _inc(es.word(bx+3));
+ goto gotsoldframe;
+soldierwait:
+ _cmp(data.byte(kLastweapon), 1);
+ if (!flags.z())
+ goto gotsoldframe;
+ data.word(kWatchingtime) = 10;
+ _cmp(data.byte(kManspath), 2);
+ if (!flags.z())
+ goto gotsoldframe;
+ _cmp(data.byte(kFacing), 4);
+ if (!flags.z())
+ goto gotsoldframe;
+ _inc(es.word(bx+3));
+ data.byte(kLastweapon) = -1;
+ data.byte(kCombatcount) = 0;
+gotsoldframe:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::rockstar() {
+ STACK_CHECK;
+ ax = es.word(bx+3);
+ _cmp(ax, 303);
+ if (flags.z())
+ goto rockcombatend;
+ _cmp(ax, 118);
+ if (flags.z())
+ goto rockcombatend;
+ checkspeed();
+ if (!flags.z())
+ goto rockspeed;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 118);
+ if (!flags.z())
+ goto notbeforedead;
+ data.byte(kMandead) = 2;
+ goto gotrockframe;
+notbeforedead:
+ _cmp(ax, 79);
+ if (!flags.z())
+ goto gotrockframe;
+ _dec(ax);
+ _cmp(data.byte(kLastweapon), 1);
+ if (!flags.z())
+ goto notgunonrock;
+ data.byte(kLastweapon) = -1;
+ ax = 123;
+ goto gotrockframe;
+notgunonrock:
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 40);
+ if (!flags.z())
+ goto gotrockframe;
+ data.byte(kCombatcount) = 0;
+ ax = 79;
+gotrockframe:
+ es.word(bx+3) = ax;
+rockspeed:
+ showgamereel();
+ _cmp(es.word(bx+3), 78);
+ if (!flags.z())
+ goto notalkrock;
+ addtopeoplelist();
+ data.byte(kPointermode) = 2;
+ data.word(kWatchingtime) = 0;
+ return;
+notalkrock:
+ data.word(kWatchingtime) = 2;
+ data.byte(kPointermode) = 0;
+ al = data.byte(kMapy);
+ es.byte(bx+2) = al;
+ return;
+rockcombatend:
+ data.byte(kNewlocation) = 45;
+ showgamereel();
+}
+
+void DreamGenContext::helicopter() {
+ STACK_CHECK;
+ ax = es.word(bx+3);
+ _cmp(ax, 203);
+ if (flags.z())
+ goto heliwon;
+ checkspeed();
+ if (!flags.z())
+ goto helispeed;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 53);
+ if (!flags.z())
+ goto notbeforehdead;
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 8);
+ if (flags.c())
+ goto waitabit;
+ data.byte(kMandead) = 2;
+waitabit:
+ ax = 49;
+ goto gotheliframe;
+notbeforehdead:
+ _cmp(ax, 9);
+ if (!flags.z())
+ goto gotheliframe;
+ _dec(ax);
+ _cmp(data.byte(kLastweapon), 1);
+ if (!flags.z())
+ goto notgunonheli;
+ data.byte(kLastweapon) = -1;
+ ax = 55;
+ goto gotheliframe;
+notgunonheli:
+ ax = 5;
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 20);
+ if (!flags.z())
+ goto gotheliframe;
+ data.byte(kCombatcount) = 0;
+ ax = 9;
+gotheliframe:
+ es.word(bx+3) = ax;
+helispeed:
+ showgamereel();
+ al = data.byte(kMapx);
+ es.byte(bx+1) = al;
+ ax = es.word(bx+3);
+ _cmp(ax, 9);
+ if (!flags.c())
+ goto notwaitingheli;
+ _cmp(data.byte(kCombatcount), 7);
+ if (flags.c())
+ goto notwaitingheli;
+ data.byte(kPointermode) = 2;
+ data.word(kWatchingtime) = 0;
+ return;
+notwaitingheli:
+ data.byte(kPointermode) = 0;
+ data.word(kWatchingtime) = 2;
+ return;
+heliwon:
+ data.byte(kPointermode) = 0;
+}
+
+void DreamGenContext::mugger() {
+ STACK_CHECK;
+ ax = es.word(bx+3);
+ _cmp(ax, 138);
+ if (flags.z())
+ goto endmugger1;
+ _cmp(ax, 176);
+ if (flags.z())
+ return /* (endmugger2) */;
+ _cmp(ax, 2);
+ if (!flags.z())
+ goto havesetwatch;
+ data.word(kWatchingtime) = 175*2;
+havesetwatch:
+ checkspeed();
+ if (!flags.z())
+ goto notmugger;
+ _inc(es.word(bx+3));
+notmugger:
+ showgamereel();
+ al = data.byte(kMapx);
+ es.byte(bx+1) = al;
+ return;
+endmugger1:
+ push(es);
+ push(bx);
+ createpanel2();
+ showicon();
+ al = 41;
+ findpuztext();
+ di = 33+20;
+ bx = 104;
+ dl = 241;
+ ah = 0;
+ printdirect();
+ worktoscreen();
+ cx = 300;
+ hangon();
+ bx = pop();
+ es = pop();
+ push(es);
+ push(bx);
+ es.word(bx+3) = 140;
+ data.byte(kManspath) = 2;
+ data.byte(kFinaldest) = 2;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ al = 'W';
+ ah = 'E';
+ cl = 'T';
+ ch = 'A';
+ findexobject();
+ data.byte(kCommand) = al;
+ data.byte(kObjecttype) = 4;
+ removeobfrominv();
+ al = 'W';
+ ah = 'E';
+ cl = 'T';
+ ch = 'B';
+ findexobject();
+ data.byte(kCommand) = al;
+ data.byte(kObjecttype) = 4;
+ removeobfrominv();
+ makemainscreen();
+ al = 48;
+ bl = 68-32;
+ bh = 54+64;
+ cx = 70;
+ dx = 10;
+ setuptimeduse();
+ data.byte(kBeenmugged) = 1;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::aide() {
+ STACK_CHECK;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::businessman() {
+ STACK_CHECK;
+ data.byte(kPointermode) = 0;
+ data.word(kWatchingtime) = 2;
+ ax = es.word(bx+3);
+ _cmp(ax, 2);
+ if (!flags.z())
+ goto notfirstbiz;
+ push(ax);
+ push(bx);
+ push(es);
+ al = 49;
+ cx = 30;
+ dx = 1;
+ bl = 68;
+ bh = 174;
+ setuptimeduse();
+ es = pop();
+ bx = pop();
+ ax = pop();
+notfirstbiz:
+ _cmp(ax, 95);
+ if (flags.z())
+ goto buscombatwonend;
+ _cmp(ax, 49);
+ if (flags.z())
+ return /* (buscombatend) */;
+ checkspeed();
+ if (!flags.z())
+ goto busspeed;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 48);
+ if (!flags.z())
+ goto notbeforedeadb;
+ data.byte(kMandead) = 2;
+ goto gotbusframe;
+notbeforedeadb:
+ _cmp(ax, 15);
+ if (!flags.z())
+ goto buscombatwon;
+ _dec(ax);
+ _cmp(data.byte(kLastweapon), 3);
+ if (!flags.z())
+ goto notshieldonbus;
+ data.byte(kLastweapon) = -1;
+ data.byte(kCombatcount) = 0;
+ ax = 51;
+ goto gotbusframe;
+notshieldonbus:
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 20);
+ if (!flags.z())
+ goto gotbusframe;
+ data.byte(kCombatcount) = 0;
+ ax = 15;
+ goto gotbusframe;
+buscombatwon:
+ _cmp(ax, 91);
+ if (!flags.z())
+ goto gotbusframe;
+ push(bx);
+ push(es);
+ al = 0;
+ turnpathon();
+ al = 1;
+ turnpathon();
+ al = 2;
+ turnpathon();
+ al = 3;
+ turnpathoff();
+ data.byte(kManspath) = 5;
+ data.byte(kFinaldest) = 5;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ es = pop();
+ bx = pop();
+ ax = 92;
+ goto gotbusframe;
+gotbusframe:
+ es.word(bx+3) = ax;
+busspeed:
+ showgamereel();
+ al = data.byte(kMapy);
+ es.byte(bx+2) = al;
+ ax = es.word(bx+3);
+ _cmp(ax, 14);
+ if (!flags.z())
+ return /* (buscombatend) */;
+ data.word(kWatchingtime) = 0;
+ data.byte(kPointermode) = 2;
+ return;
+buscombatwonend:
+ data.byte(kPointermode) = 0;
+ data.word(kWatchingtime) = 0;
+}
+
+void DreamGenContext::poolguard() {
+ STACK_CHECK;
+ ax = es.word(bx+3);
+ _cmp(ax, 214);
+ if (flags.z())
+ goto combatover2;
+ _cmp(ax, 258);
+ if (flags.z())
+ goto combatover2;
+ _cmp(ax, 185);
+ if (flags.z())
+ goto combatover1;
+ _cmp(ax, 0);
+ if (!flags.z())
+ goto notfirstpool;
+ al = 0;
+ turnpathon();
+notfirstpool:
+ checkspeed();
+ if (!flags.z())
+ goto guardspeed;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 122);
+ if (!flags.z())
+ goto notendguard1;
+ _dec(ax);
+ _cmp(data.byte(kLastweapon), 2);
+ if (!flags.z())
+ goto notaxeonpool;
+ data.byte(kLastweapon) = -1;
+ ax = 122;
+ goto gotguardframe;
+notaxeonpool:
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 40);
+ if (!flags.z())
+ goto gotguardframe;
+ data.byte(kCombatcount) = 0;
+ ax = 195;
+ goto gotguardframe;
+notendguard1:
+ _cmp(ax, 147);
+ if (!flags.z())
+ goto gotguardframe;
+ _dec(ax);
+ _cmp(data.byte(kLastweapon), 1);
+ if (!flags.z())
+ goto notgunonpool;
+ data.byte(kLastweapon) = -1;
+ ax = 147;
+ goto gotguardframe;
+notgunonpool:
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 40);
+ if (!flags.z())
+ goto gotguardframe;
+ data.byte(kCombatcount) = 0;
+ ax = 220;
+gotguardframe:
+ es.word(bx+3) = ax;
+guardspeed:
+ showgamereel();
+ ax = es.word(bx+3);
+ _cmp(ax, 121);
+ if (flags.z())
+ goto iswaitingpool;
+ _cmp(ax, 146);
+ if (flags.z())
+ goto iswaitingpool;
+ data.byte(kPointermode) = 0;
+ data.word(kWatchingtime) = 2;
+ return;
+iswaitingpool:
+ data.byte(kPointermode) = 2;
+ data.word(kWatchingtime) = 0;
+ return;
+combatover1:
+ data.word(kWatchingtime) = 0;
+ data.byte(kPointermode) = 0;
+ al = 0;
+ turnpathon();
+ al = 1;
+ turnpathoff();
+ return;
+combatover2:
+ showgamereel();
+ data.word(kWatchingtime) = 2;
+ data.byte(kPointermode) = 0;
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 100);
+ if (flags.c())
+ return /* (doneover2) */;
+ data.word(kWatchingtime) = 0;
+ data.byte(kMandead) = 2;
+}
+
+void DreamGenContext::security() {
+ STACK_CHECK;
+ _cmp(es.word(bx+3), 32);
+ if (flags.z())
+ goto securwait;
+ _cmp(es.word(bx+3), 69);
+ if (!flags.z())
+ goto notaftersec;
+ return;
+notaftersec:
+ data.word(kWatchingtime) = 10;
+ checkspeed();
+ if (!flags.z())
+ goto gotsecurframe;
+ _inc(es.word(bx+3));
+ goto gotsecurframe;
+securwait:
+ _cmp(data.byte(kLastweapon), 1);
+ if (!flags.z())
+ goto gotsecurframe;
+ data.word(kWatchingtime) = 10;
+ _cmp(data.byte(kManspath), 9);
+ if (!flags.z())
+ goto gotsecurframe;
+ _cmp(data.byte(kFacing), 0);
+ if (!flags.z())
+ goto gotsecurframe;
+ data.byte(kLastweapon) = -1;
+ _inc(es.word(bx+3));
+gotsecurframe:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::heavy() {
+ STACK_CHECK;
+ al = es.byte(bx+7);
+ _and(al, 127);
+ es.byte(bx+7) = al;
+ _cmp(es.word(bx+3), 43);
+ if (flags.z())
+ goto heavywait;
+ data.word(kWatchingtime) = 10;
+ _cmp(es.word(bx+3), 70);
+ if (!flags.z())
+ goto notafterhshot;
+ _inc(data.byte(kCombatcount));
+ _cmp(data.byte(kCombatcount), 80);
+ if (!flags.z())
+ goto gotheavyframe;
+ data.byte(kMandead) = 2;
+ goto gotheavyframe;
+notafterhshot:
+ checkspeed();
+ if (!flags.z())
+ goto gotheavyframe;
+ _inc(es.word(bx+3));
+ goto gotheavyframe;
+heavywait:
+ _cmp(data.byte(kLastweapon), 1);
+ if (!flags.z())
+ goto gotheavyframe;
+ _cmp(data.byte(kManspath), 5);
+ if (!flags.z())
+ goto gotheavyframe;
+ _cmp(data.byte(kFacing), 4);
+ if (!flags.z())
+ goto gotheavyframe;
+ data.byte(kLastweapon) = -1;
+ _inc(es.word(bx+3));
+ data.byte(kCombatcount) = 0;
+gotheavyframe:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::bossman() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto notboss;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 4);
+ if (flags.z())
+ goto firstdes;
+ _cmp(ax, 20);
+ if (flags.z())
+ goto secdes;
+ _cmp(ax, 41);
+ if (!flags.z())
+ goto gotallboss;
+ ax = 0;
+ _inc(data.byte(kGunpassflag));
+ es.byte(bx+7) = 10;
+ goto gotallboss;
+firstdes:
+ _cmp(data.byte(kGunpassflag), 1);
+ if (flags.z())
+ goto gotallboss;
+ push(ax);
+ randomnumber();
+ cl = al;
+ ax = pop();
+ _cmp(cl, 10);
+ if (flags.c())
+ goto gotallboss;
+ ax = 0;
+ goto gotallboss;
+secdes:
+ _cmp(data.byte(kGunpassflag), 1);
+ if (flags.z())
+ goto gotallboss;
+ ax = 0;
+gotallboss:
+ es.word(bx+3) = ax;
+notboss:
+ showgamereel();
+ addtopeoplelist();
+ al = es.byte(bx+7);
+ _and(al, 128);
+ if (flags.z())
+ return /* (nottalkedboss) */;
+ data.byte(kTalkedtoboss) = 1;
+}
+
+void DreamGenContext::gamer() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto gamerfin;
+gameragain:
+ randomnum1();
+ _and(al, 7);
+ _cmp(al, 5);
+ if (!flags.c())
+ goto gameragain;
+ _add(al, 20);
+ _cmp(al, es.byte(bx+3));
+ if (flags.z())
+ goto gameragain;
+ ah = 0;
+ es.word(bx+3) = ax;
+gamerfin:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::sparkydrip() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ return /* (cantdrip) */;
+ al = 14;
+ ah = 0;
+ playchannel0();
+}
+
+void DreamGenContext::carparkdrip() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ return /* (cantdrip2) */;
+ al = 14;
+ playchannel1();
+}
+
+void DreamGenContext::keeper() {
+ STACK_CHECK;
+ _cmp(data.byte(kKeeperflag), 0);
+ if (!flags.z())
+ goto notwaiting;
+ _cmp(data.word(kReeltowatch), 190);
+ if (flags.c())
+ return /* (waiting) */;
+ _inc(data.byte(kKeeperflag));
+ ah = es.byte(bx+7);
+ _and(ah, 127);
+ _cmp(ah, data.byte(kDreamnumber));
+ if (flags.z())
+ return /* (notdiff) */;
+ al = data.byte(kDreamnumber);
+ es.byte(bx+7) = al;
+ return;
+notwaiting:
+ addtopeoplelist();
+ showgamereel();
+}
+
+void DreamGenContext::candles1() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto candle1;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 44);
+ if (!flags.z())
+ goto notendcandle1;
+ ax = 39;
+notendcandle1:
+ es.word(bx+3) = ax;
+candle1:
+ showgamereel();
+}
+
+void DreamGenContext::smallcandle() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto smallcandlef;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 37);
+ if (!flags.z())
+ goto notendsmallcandle;
+ ax = 25;
+notendsmallcandle:
+ es.word(bx+3) = ax;
+smallcandlef:
+ showgamereel();
+}
+
+void DreamGenContext::intromagic1() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto introm1fin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 145);
+ if (!flags.z())
+ goto gotintrom1;
+ ax = 121;
+gotintrom1:
+ es.word(bx+3) = ax;
+ _cmp(ax, 121);
+ if (!flags.z())
+ goto introm1fin;
+ _inc(data.byte(kIntrocount));
+ push(es);
+ push(bx);
+ intro1text();
+ bx = pop();
+ es = pop();
+ _cmp(data.byte(kIntrocount), 8);
+ if (!flags.z())
+ goto introm1fin;
+ _add(data.byte(kMapy), 10);
+ data.byte(kNowinnewroom) = 1;
+introm1fin:
+ showgamereel();
+}
+
+void DreamGenContext::candles() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto candlesfin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 167);
+ if (!flags.z())
+ goto gotcandles;
+ ax = 162;
+gotcandles:
+ es.word(bx+3) = ax;
+candlesfin:
+ showgamereel();
+}
+
+void DreamGenContext::candles2() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto candles2fin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 238);
+ if (!flags.z())
+ goto gotcandles2;
+ ax = 233;
+gotcandles2:
+ es.word(bx+3) = ax;
+candles2fin:
+ showgamereel();
+}
+
+void DreamGenContext::gates() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto gatesfin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 116);
+ if (!flags.z())
+ goto notbang;
+ push(ax);
+ push(bx);
+ push(es);
+ al = 17;
+ playchannel1();
+ es = pop();
+ bx = pop();
+ ax = pop();
+notbang:
+ _cmp(ax, 110);
+ if (flags.c())
+ goto slowgates;
+ es.byte(bx+5) = 2;
+slowgates:
+ _cmp(ax, 120);
+ if (!flags.z())
+ goto gotgates;
+ data.byte(kGetback) = 1;
+ ax = 119;
+gotgates:
+ es.word(bx+3) = ax;
+ push(es);
+ push(bx);
+ intro3text();
+ bx = pop();
+ es = pop();
+gatesfin:
+ showgamereel();
+}
+
+void DreamGenContext::intromagic2() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto introm2fin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 216);
+ if (!flags.z())
+ goto gotintrom2;
+ ax = 192;
+gotintrom2:
+ es.word(bx+3) = ax;
+introm2fin:
+ showgamereel();
+}
+
+void DreamGenContext::intromagic3() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto introm3fin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 218);
+ if (!flags.z())
+ goto gotintrom3;
+ data.byte(kGetback) = 1;
+gotintrom3:
+ es.word(bx+3) = ax;
+introm3fin:
+ showgamereel();
+ al = data.byte(kMapx);
+ es.byte(bx+1) = al;
+}
+
+void DreamGenContext::intromonks1() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto intromonk1fin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 80);
+ if (!flags.z())
+ goto notendmonk1;
+ _add(data.byte(kMapy), 10);
+ data.byte(kNowinnewroom) = 1;
+ showgamereel();
+ return;
+notendmonk1:
+ _cmp(ax, 30);
+ if (!flags.z())
+ goto gotintromonk1;
+ _sub(data.byte(kMapy), 10);
+ data.byte(kNowinnewroom) = 1;
+ ax = 51;
+gotintromonk1:
+ es.word(bx+3) = ax;
+ _cmp(ax, 5);
+ if (flags.z())
+ goto waitstep;
+ _cmp(ax, 15);
+ if (flags.z())
+ goto waitstep;
+ _cmp(ax, 25);
+ if (flags.z())
+ goto waitstep;
+ _cmp(ax, 61);
+ if (flags.z())
+ goto waitstep;
+ _cmp(ax, 71);
+ if (flags.z())
+ goto waitstep;
+ goto intromonk1fin;
+waitstep:
+ push(es);
+ push(bx);
+ intro2text();
+ bx = pop();
+ es = pop();
+ es.byte(bx+6) = -20;
+intromonk1fin:
+ showgamereel();
+ al = data.byte(kMapy);
+ es.byte(bx+2) = al;
+}
+
+void DreamGenContext::intromonks2() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto intromonk2fin;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 87);
+ if (!flags.z())
+ goto nottalk1;
+ _inc(data.byte(kIntrocount));
+ push(es);
+ push(bx);
+ monks2text();
+ bx = pop();
+ es = pop();
+ _cmp(data.byte(kIntrocount), 19);
+ if (!flags.z())
+ goto notlasttalk1;
+ ax = 87;
+ goto gotintromonk2;
+notlasttalk1:
+ ax = 74;
+ goto gotintromonk2;
+nottalk1:
+ _cmp(ax, 110);
+ if (!flags.z())
+ goto notraisearm;
+ _inc(data.byte(kIntrocount));
+ push(es);
+ push(bx);
+ monks2text();
+ bx = pop();
+ es = pop();
+ _cmp(data.byte(kIntrocount), 35);
+ if (!flags.z())
+ goto notlastraise;
+ ax = 111;
+ goto gotintromonk2;
+notlastraise:
+ ax = 98;
+ goto gotintromonk2;
+notraisearm:
+ _cmp(ax, 176);
+ if (!flags.z())
+ goto notendmonk2;
+ data.byte(kGetback) = 1;
+ goto gotintromonk2;
+notendmonk2:
+ _cmp(ax, 125);
+ if (!flags.z())
+ goto gotintromonk2;
+ ax = 140;
+gotintromonk2:
+ es.word(bx+3) = ax;
+intromonk2fin:
+ showgamereel();
+}
+
+void DreamGenContext::handclap() {
+ STACK_CHECK;
+}
+
+void DreamGenContext::monks2text() {
+ STACK_CHECK;
+ _cmp(data.byte(kIntrocount), 1);
+ if (!flags.z())
+ goto notmonk2text1;
+ al = 8;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text1:
+ _cmp(data.byte(kIntrocount), 4);
+ if (!flags.z())
+ goto notmonk2text2;
+ al = 9;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text2:
+ _cmp(data.byte(kIntrocount), 7);
+ if (!flags.z())
+ goto notmonk2text3;
+ al = 10;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text3:
+ _cmp(data.byte(kIntrocount), 10);
+ if (!flags.z())
+ goto notmonk2text4;
+ data.byte(kIntrocount) = 12;
+ al = 11;
+ bl = 0;
+ bh = 105;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text4:
+ _cmp(data.byte(kIntrocount), 13);
+ if (!flags.z())
+ goto notmonk2text5;
+ data.byte(kIntrocount) = 17;
+ return;
+ al = 12;
+ bl = 0;
+ bh = 120;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text5:
+ _cmp(data.byte(kIntrocount), 16);
+ if (!flags.z())
+ goto notmonk2text6;
+ al = 13;
+ bl = 0;
+ bh = 135;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text6:
+ _cmp(data.byte(kIntrocount), 19);
+ if (!flags.z())
+ goto notmonk2text7;
+ al = 14;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ dx = 1;
+ ah = 82;
+ { setuptimedtemp(); return; };
+notmonk2text7:
+ _cmp(data.byte(kIntrocount), 22);
+ if (!flags.z())
+ goto notmonk2text8;
+ al = 15;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text8:
+ _cmp(data.byte(kIntrocount), 25);
+ if (!flags.z())
+ goto notmonk2text9;
+ al = 16;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text9:
+ _cmp(data.byte(kIntrocount), 27);
+ if (!flags.z())
+ goto notmonk2text10;
+ al = 17;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ goto gotmonks2text;
+notmonk2text10:
+ _cmp(data.byte(kIntrocount), 31);
+ if (!flags.z())
+ return /* (notmonk2text11) */;
+ al = 18;
+ bl = 36;
+ bh = 160;
+ cx = 100;
+ goto gotmonks2text;
+ return;
+gotmonks2text:
+ dx = 1;
+ cx = 120;
+ ah = 82;
+ setuptimedtemp();
+}
+
+void DreamGenContext::intro1text() {
+ STACK_CHECK;
+ _cmp(data.byte(kIntrocount), 2);
+ if (!flags.z())
+ goto notintro1text1;
+ al = 40;
+ bl = 34;
+ bh = 130;
+ cx = 90;
+ goto gotintro1text;
+notintro1text1:
+ _cmp(data.byte(kIntrocount), 4);
+ if (!flags.z())
+ goto notintro1text2;
+ al = 41;
+ bl = 34;
+ bh = 130;
+ cx = 90;
+ goto gotintro1text;
+notintro1text2:
+ _cmp(data.byte(kIntrocount), 6);
+ if (!flags.z())
+ return /* (notintro1text3) */;
+ al = 42;
+ bl = 34;
+ bh = 130;
+ cx = 90;
+ goto gotintro1text;
+ return;
+gotintro1text:
+ dx = 1;
+ ah = 82;
+ _cmp(data.byte(kCh1playing), 255);
+ if (flags.z())
+ goto oktalk2;
+ _dec(data.byte(kIntrocount));
+ return;
+oktalk2:
+ setuptimedtemp();
+}
+
+void DreamGenContext::intro2text() {
+ STACK_CHECK;
+ _cmp(ax, 5);
+ if (!flags.z())
+ goto notintro2text1;
+ al = 43;
+ bl = 34;
+ bh = 40;
+ cx = 90;
+ goto gotintro2text;
+notintro2text1:
+ _cmp(ax, 15);
+ if (!flags.z())
+ return /* (notintro2text2) */;
+ al = 44;
+ bl = 34;
+ bh = 40;
+ cx = 90;
+ goto gotintro2text;
+ return;
+gotintro2text:
+ dx = 1;
+ ah = 82;
+ setuptimedtemp();
+}
+
+void DreamGenContext::intro3text() {
+ STACK_CHECK;
+ _cmp(ax, 107);
+ if (!flags.z())
+ goto notintro3text1;
+ al = 45;
+ bl = 36;
+ bh = 56;
+ cx = 100;
+ goto gotintro3text;
+notintro3text1:
+ _cmp(ax, 108);
+ if (!flags.z())
+ return /* (notintro3text2) */;
+ al = 46;
+ bl = 36;
+ bh = 56;
+ cx = 100;
+ goto gotintro3text;
+ return;
+gotintro3text:
+ dx = 1;
+ ah = 82;
+ setuptimedtemp();
+}
+
+void DreamGenContext::monkandryan() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto notmonkryan;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 83);
+ if (!flags.z())
+ goto gotmonkryan;
+ _inc(data.byte(kIntrocount));
+ push(es);
+ push(bx);
+ textformonk();
+ bx = pop();
+ es = pop();
+ ax = 77;
+ _cmp(data.byte(kIntrocount), 57);
+ if (!flags.z())
+ goto gotmonkryan;
+ data.byte(kGetback) = 1;
+ return;
+gotmonkryan:
+ es.word(bx+3) = ax;
+notmonkryan:
+ showgamereel();
+}
+
+void DreamGenContext::endgameseq() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto notendseq;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 51);
+ if (!flags.z())
+ goto gotendseq;
+ _cmp(data.byte(kIntrocount), 140);
+ if (flags.z())
+ goto gotendseq;
+ _inc(data.byte(kIntrocount));
+ push(es);
+ push(bx);
+ textforend();
+ bx = pop();
+ es = pop();
+ ax = 50;
+gotendseq:
+ es.word(bx+3) = ax;
+ _cmp(ax, 134);
+ if (!flags.z())
+ goto notfadedown;
+ push(es);
+ push(bx);
+ push(ax);
+ fadescreendownhalf();
+ ax = pop();
+ bx = pop();
+ es = pop();
+ goto notendseq;
+notfadedown:
+ _cmp(ax, 324);
+ if (!flags.z())
+ goto notfadeend;
+ push(es);
+ push(bx);
+ push(ax);
+ fadescreendowns();
+ data.byte(kVolumeto) = 7;
+ data.byte(kVolumedirection) = 1;
+ ax = pop();
+ bx = pop();
+ es = pop();
+notfadeend:
+ _cmp(ax, 340);
+ if (!flags.z())
+ goto notendseq;
+ data.byte(kGetback) = 1;
+notendseq:
+ showgamereel();
+ al = data.byte(kMapy);
+ es.byte(bx+2) = al;
+ ax = es.word(bx+3);
+ _cmp(ax, 145);
+ if (!flags.z())
+ return /* (notendcreds) */;
+ es.word(bx+3) = 146;
+ rollendcredits();
+}
+
+void DreamGenContext::rollendcredits() {
+ STACK_CHECK;
+ al = 16;
+ ah = 255;
+ playchannel0();
+ data.byte(kVolume) = 7;
+ data.byte(kVolumeto) = 0;
+ data.byte(kVolumedirection) = -1;
+ cl = 160;
+ ch = 160;
+ di = 75;
+ bx = 20;
+ ds = data.word(kMapstore);
+ si = 0;
+ multiget();
+ es = data.word(kTextfile1);
+ si = 3*2;
+ ax = es.word(si);
+ si = ax;
+ _add(si, (66*2));
+ cx = 254;
+endcredits1:
+ push(cx);
+ bx = 10;
+ cx = data.word(kLinespacing);
+endcredits2:
+ push(cx);
+ push(si);
+ push(di);
+ push(es);
+ push(bx);
+ vsync();
+ cl = 160;
+ ch = 160;
+ di = 75;
+ bx = 20;
+ ds = data.word(kMapstore);
+ si = 0;
+ multiput();
+ vsync();
+ bx = pop();
+ es = pop();
+ di = pop();
+ si = pop();
+ push(si);
+ push(di);
+ push(es);
+ push(bx);
+ cx = 18;
+onelot:
+ push(cx);
+ di = 75;
+ dx = 161;
+ ax = 0;
+ printdirect();
+ _add(bx, data.word(kLinespacing));
+ cx = pop();
+ if (--cx)
+ goto onelot;
+ vsync();
+ cl = 160;
+ ch = 160;
+ di = 75;
+ bx = 20;
+ multidump();
+ bx = pop();
+ es = pop();
+ di = pop();
+ si = pop();
+ cx = pop();
+ _dec(bx);
+ if (--cx)
+ goto endcredits2;
+ cx = pop();
+looknext:
+ al = es.byte(si);
+ _inc(si);
+ _cmp(al, ':');
+ if (flags.z())
+ goto gotnext;
+ _cmp(al, 0);
+ if (flags.z())
+ goto gotnext;
+ goto looknext;
+gotnext:
+ if (--cx)
+ goto endcredits1;
+ cx = 100;
+ hangon();
+ paneltomap();
+ fadescreenuphalf();
+}
+
+void DreamGenContext::priest() {
+ STACK_CHECK;
+ _cmp(es.word(bx+3), 8);
+ if (flags.z())
+ return /* (priestspoken) */;
+ data.byte(kPointermode) = 0;
+ data.word(kWatchingtime) = 2;
+ checkspeed();
+ if (!flags.z())
+ return /* (priestwait) */;
+ _inc(es.word(bx+3));
+ push(es);
+ push(bx);
+ priesttext();
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::madmanstelly() {
+ STACK_CHECK;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 307);
+ if (!flags.z())
+ goto notendtelly;
+ ax = 300;
+notendtelly:
+ es.word(bx+3) = ax;
+ showgamereel();
+}
+
+void DreamGenContext::madman() {
+ STACK_CHECK;
+ data.word(kWatchingtime) = 2;
+ checkspeed();
+ if (!flags.z())
+ goto nomadspeed;
+ ax = es.word(bx+3);
+ _cmp(ax, 364);
+ if (!flags.c())
+ goto ryansded;
+ _cmp(ax, 10);
+ if (!flags.z())
+ goto notfirstmad;
+ push(es);
+ push(bx);
+ push(ax);
+ dx = 2247;
+ loadtemptext();
+ ax = pop();
+ bx = pop();
+ es = pop();
+ data.byte(kCombatcount) = -1;
+ data.byte(kSpeechcount) = 0;
+notfirstmad:
+ _inc(ax);
+ _cmp(ax, 294);
+ if (flags.z())
+ goto madmanspoken;
+ _cmp(ax, 66);
+ if (!flags.z())
+ goto nomadspeak;
+ _inc(data.byte(kCombatcount));
+ push(es);
+ push(bx);
+ madmantext();
+ bx = pop();
+ es = pop();
+ ax = 53;
+ _cmp(data.byte(kCombatcount), 64);
+ if (flags.c())
+ goto nomadspeak;
+ _cmp(data.byte(kCombatcount), 70);
+ if (flags.z())
+ goto killryan;
+ _cmp(data.byte(kLastweapon), 8);
+ if (!flags.z())
+ goto nomadspeak;
+ data.byte(kCombatcount) = 72;
+ data.byte(kLastweapon) = -1;
+ data.byte(kMadmanflag) = 1;
+ ax = 67;
+ goto nomadspeak;
+killryan:
+ ax = 310;
+nomadspeak:
+ es.word(bx+3) = ax;
+nomadspeed:
+ showgamereel();
+ al = data.byte(kMapx);
+ es.byte(bx+1) = al;
+ madmode();
+ return;
+madmanspoken:
+ _cmp(data.byte(kWongame), 1);
+ if (flags.z())
+ return /* (alreadywon) */;
+ data.byte(kWongame) = 1;
+ push(es);
+ push(bx);
+ getridoftemptext();
+ bx = pop();
+ es = pop();
+ return;
+ryansded:
+ data.byte(kMandead) = 2;
+ showgamereel();
+}
+
+void DreamGenContext::madmantext() {
+ STACK_CHECK;
+ _cmp(data.byte(kSpeechcount), 63);
+ if (!flags.c())
+ return /* (nomadtext) */;
+ _cmp(data.byte(kCh1playing), 255);
+ if (!flags.z())
+ return /* (nomadtext) */;
+ al = data.byte(kSpeechcount);
+ _inc(data.byte(kSpeechcount));
+ _add(al, 47);
+ bl = 72;
+ bh = 80;
+ cx = 90;
+ dx = 1;
+ ah = 82;
+ setuptimedtemp();
+}
+
+void DreamGenContext::madmode() {
+ STACK_CHECK;
+ data.word(kWatchingtime) = 2;
+ data.byte(kPointermode) = 0;
+ _cmp(data.byte(kCombatcount), 65);
+ if (flags.c())
+ return /* (iswatchmad) */;
+ _cmp(data.byte(kCombatcount), 70);
+ if (!flags.c())
+ return /* (iswatchmad) */;
+ data.byte(kPointermode) = 2;
+}
+
+void DreamGenContext::priesttext() {
+ STACK_CHECK;
+ _cmp(es.word(bx+3), 2);
+ if (flags.c())
+ return /* (nopriesttext) */;
+ _cmp(es.word(bx+3), 7);
+ if (!flags.c())
+ return /* (nopriesttext) */;
+ al = es.byte(bx+3);
+ _and(al, 1);
+ if (!flags.z())
+ return /* (nopriesttext) */;
+ al = es.byte(bx+3);
+ _shr(al, 1);
+ _add(al, 50);
+ bl = 72;
+ bh = 80;
+ cx = 54;
+ dx = 1;
+ setuptimeduse();
+}
+
+void DreamGenContext::textforend() {
+ STACK_CHECK;
+ _cmp(data.byte(kIntrocount), 20);
+ if (!flags.z())
+ goto notendtext1;
+ al = 0;
+ bl = 34;
+ bh = 20;
+ cx = 60;
+ goto gotendtext;
+notendtext1:
+ _cmp(data.byte(kIntrocount), 50);
+ if (!flags.z())
+ goto notendtext2;
+ al = 1;
+ bl = 34;
+ bh = 20;
+ cx = 60;
+ goto gotendtext;
+notendtext2:
+ _cmp(data.byte(kIntrocount), 85);
+ if (!flags.z())
+ return /* (notendtext3) */;
+ al = 2;
+ bl = 34;
+ bh = 20;
+ cx = 60;
+ goto gotendtext;
+ return;
+gotendtext:
+ dx = 1;
+ ah = 83;
+ setuptimedtemp();
+}
+
+void DreamGenContext::textformonk() {
+ STACK_CHECK;
+ _cmp(data.byte(kIntrocount), 1);
+ if (!flags.z())
+ goto notmonktext1;
+ al = 19;
+ bl = 68;
+ bh = 154;
+ cx = 120;
+ goto gotmonktext;
+notmonktext1:
+ _cmp(data.byte(kIntrocount), 5);
+ if (!flags.z())
+ goto notmonktext2;
+ al = 20;
+ bl = 68;
+ bh = 38;
+ cx = 120;
+ goto gotmonktext;
+notmonktext2:
+ _cmp(data.byte(kIntrocount), 9);
+ if (!flags.z())
+ goto notmonktext3;
+ al = 21;
+ bl = 48;
+ bh = 154;
+ cx = 120;
+ goto gotmonktext;
+notmonktext3:
+ _cmp(data.byte(kIntrocount), 13);
+ if (!flags.z())
+ goto notmonktext4;
+ al = 22;
+ bl = 68;
+ bh = 38;
+ cx = 120;
+ goto gotmonktext;
+notmonktext4:
+ _cmp(data.byte(kIntrocount), 15);
+ if (!flags.z())
+ goto notmonktext5;
+ al = 23;
+ bl = 68;
+ bh = 154;
+ cx = 120;
+ goto gotmonktext;
+notmonktext5:
+ _cmp(data.byte(kIntrocount), 21);
+ if (!flags.z())
+ goto notmonktext6;
+ al = 24;
+ bl = 68;
+ bh = 38;
+ cx = 120;
+ goto gotmonktext;
+notmonktext6:
+ _cmp(data.byte(kIntrocount), 25);
+ if (!flags.z())
+ goto notmonktext7;
+ al = 25;
+ bl = 68;
+ bh = 154;
+ cx = 120;
+ goto gotmonktext;
+notmonktext7:
+ _cmp(data.byte(kIntrocount), 29);
+ if (!flags.z())
+ goto notmonktext8;
+ al = 26;
+ bl = 68;
+ bh = 38;
+ cx = 120;
+ goto gotmonktext;
+notmonktext8:
+ _cmp(data.byte(kIntrocount), 33);
+ if (!flags.z())
+ goto notmonktext9;
+ al = 27;
+ bl = 68;
+ bh = 154;
+ cx = 120;
+ goto gotmonktext;
+notmonktext9:
+ _cmp(data.byte(kIntrocount), 37);
+ if (!flags.z())
+ goto notmonktext10;
+ al = 28;
+ bl = 68;
+ bh = 154;
+ cx = 120;
+ goto gotmonktext;
+notmonktext10:
+ _cmp(data.byte(kIntrocount), 41);
+ if (!flags.z())
+ goto notmonktext11;
+ al = 29;
+ bl = 68;
+ bh = 38;
+ cx = 120;
+ goto gotmonktext;
+notmonktext11:
+ _cmp(data.byte(kIntrocount), 45);
+ if (!flags.z())
+ goto notmonktext12;
+ al = 30;
+ bl = 68;
+ bh = 154;
+ cx = 120;
+ goto gotmonktext;
+notmonktext12:
+ _cmp(data.byte(kIntrocount), 52);
+ if (!flags.z())
+ goto notmonktext13;
+ al = 31;
+ bl = 68;
+ bh = 154;
+ cx = 220;
+ goto gotmonktext;
+notmonktext13:
+ _cmp(data.byte(kIntrocount), 53);
+ if (!flags.z())
+ return /* (notendtitles) */;
+ fadescreendowns();
+ data.byte(kVolumeto) = 7;
+ data.byte(kVolumedirection) = 1;
+ return;
+gotmonktext:
+ dx = 1;
+ ah = 82;
+ _cmp(data.byte(kCh1playing), 255);
+ if (flags.z())
+ goto oktalk;
+ _dec(data.byte(kIntrocount));
+ return;
+oktalk:
+ setuptimedtemp();
+}
+
+void DreamGenContext::drunk() {
+ STACK_CHECK;
+ _cmp(data.byte(kGeneraldead), 0);
+ if (!flags.z())
+ return /* (trampgone) */;
+ al = es.byte(bx+7);
+ _and(al, 127);
+ es.byte(bx+7) = al;
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::advisor() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto noadvisor;
+ goto noadvisor;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 123);
+ if (!flags.z())
+ goto notendadvis;
+ ax = 106;
+ goto gotadvframe;
+notendadvis:
+ _cmp(ax, 108);
+ if (!flags.z())
+ goto gotadvframe;
+ push(ax);
+ randomnumber();
+ cl = al;
+ ax = pop();
+ _cmp(cl, 3);
+ if (flags.c())
+ goto gotadvframe;
+ ax = 106;
+gotadvframe:
+ es.word(bx+3) = ax;
+noadvisor:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::copper() {
+ STACK_CHECK;
+ checkspeed();
+ if (!flags.z())
+ goto nocopper;
+ ax = es.word(bx+3);
+ _inc(ax);
+ _cmp(ax, 94);
+ if (!flags.z())
+ goto notendcopper;
+ ax = 64;
+ goto gotcopframe;
+notendcopper:
+ _cmp(ax, 81);
+ if (flags.z())
+ goto mightwait;
+ _cmp(ax, 66);
+ if (!flags.z())
+ goto gotcopframe;
+mightwait:
+ push(ax);
+ randomnumber();
+ cl = al;
+ ax = pop();
+ _cmp(cl, 7);
+ if (flags.c())
+ goto gotcopframe;
+ _dec(ax);
+gotcopframe:
+ es.word(bx+3) = ax;
+nocopper:
+ showgamereel();
+ addtopeoplelist();
+}
+
+void DreamGenContext::sparky() {
+ STACK_CHECK;
+ _cmp(data.word(kCard1money), 0);
+ if (flags.z())
+ goto animsparky;
+ es.byte(bx+7) = 3;
+ goto animsparky;
+animsparky:
+ checkspeed();
+ if (!flags.z())
+ goto finishsparky;
+ _cmp(es.word(bx+3), 34);
+ if (!flags.z())
+ goto notsparky1;
+ randomnumber();
+ _cmp(al, 30);
+ if (flags.c())
+ goto dosparky;
+ es.word(bx+3) = 27;
+ goto finishsparky;
+notsparky1:
+ _cmp(es.word(bx+3), 48);
+ if (!flags.z())
+ goto dosparky;
+ es.word(bx+3) = 27;
+ goto finishsparky;
+dosparky:
+ _inc(es.word(bx+3));
+finishsparky:
+ showgamereel();
+ addtopeoplelist();
+ al = es.byte(bx+7);
+ _and(al, 128);
+ if (flags.z())
+ return /* (nottalkedsparky) */;
+ data.byte(kTalkedtosparky) = 1;
+}
+
+void DreamGenContext::train() {
+ STACK_CHECK;
+ return;
+ ax = es.word(bx+3);
+ _cmp(ax, 21);
+ if (!flags.c())
+ goto notrainyet;
+ _inc(ax);
+ goto gottrainframe;
+notrainyet:
+ randomnumber();
+ _cmp(al, 253);
+ if (flags.c())
+ return /* (notrainatall) */;
+ _cmp(data.byte(kManspath), 5);
+ if (!flags.z())
+ return /* (notrainatall) */;
+ _cmp(data.byte(kFinaldest), 5);
+ if (!flags.z())
+ return /* (notrainatall) */;
+ ax = 5;
+gottrainframe:
+ es.word(bx+3) = ax;
+ showgamereel();
+}
+
+void DreamGenContext::addtopeoplelist() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ push(bx);
+ cl = es.byte(bx+7);
+ ax = es.word(bx+3);
+ bx = data.word(kListpos);
+ es = data.word(kBuffers);
+ es.word(bx) = ax;
+ ax = pop();
+ es.word(bx+2) = ax;
+ es.byte(bx+4) = cl;
+ bx = pop();
+ es = pop();
+ _add(data.word(kListpos), 5);
+}
+
+void DreamGenContext::showgamereel() {
+ STACK_CHECK;
+ ax = es.word(bx+3);
+ _cmp(ax, 512);
+ if (!flags.c())
+ return /* (noshow) */;
+ data.word(kReelpointer) = ax;
+ push(es);
+ push(bx);
+ plotreel();
+ bx = pop();
+ es = pop();
+ ax = data.word(kReelpointer);
+ es.word(bx+3) = ax;
+}
+
+void DreamGenContext::checkspeed() {
+ STACK_CHECK;
+ _cmp(data.byte(kLastweapon), -1);
+ if (!flags.z())
+ goto forcenext;
+ _inc(es.byte(bx+6));
+ al = es.byte(bx+6);
+ _cmp(al, es.byte(bx+5));
+ if (!flags.z())
+ return /* (notspeed) */;
+ al = 0;
+ es.byte(bx+6) = al;
+ _cmp(al, al);
+ return;
+forcenext:
+ _cmp(al, al);
+}
+
+void DreamGenContext::clearsprites() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
+ al = 255;
+ cx = (32)*16;
+ _stosb(cx, true);
+}
+
+void DreamGenContext::makesprite() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
+_tmp17:
+ _cmp(es.byte(bx+15), 255);
+ if (flags.z())
+ goto _tmp17a;
+ _add(bx, (32));
+ goto _tmp17;
+_tmp17a:
+ es.word(bx) = cx;
+ es.word(bx+10) = si;
+ es.word(bx+6) = dx;
+ es.word(bx+8) = di;
+ es.word(bx+2) = 0x0ffff;
+ es.byte(bx+15) = 0;
+ es.byte(bx+18) = 0;
+}
+
+void DreamGenContext::delsprite() {
+ STACK_CHECK;
+ di = bx;
+ cx = (32);
+ al = 255;
+ _stosb(cx, true);
+}
+
+void DreamGenContext::spriteupdate() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
+ al = data.byte(kRyanon);
+ es.byte(bx+31) = al;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
+ cx = 16;
+_tmp18:
+ push(cx);
+ push(bx);
+ ax = es.word(bx);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ goto _tmp18a;
+ push(es);
+ push(ds);
+ cx = es.word(bx+2);
+ es.word(bx+24) = cx;
+ __dispatch_call(ax);
+ ds = pop();
+ es = pop();
+_tmp18a:
+ bx = pop();
+ cx = pop();
+ _cmp(data.byte(kNowinnewroom), 1);
+ if (flags.z())
+ return /* ($18b) */;
+ _add(bx, (32));
+ if (--cx)
+ goto _tmp18;
+}
+
+void DreamGenContext::printsprites() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ cx = 0;
+priorityloop:
+ push(cx);
+ data.byte(kPriority) = cl;
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
+ cx = 16;
+prtspriteloop:
+ push(cx);
+ push(bx);
+ ax = es.word(bx);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ goto skipsprite;
+ al = data.byte(kPriority);
+ _cmp(al, es.byte(bx+23));
+ if (!flags.z())
+ goto skipsprite;
+ _cmp(es.byte(bx+31), 1);
+ if (flags.z())
+ goto skipsprite;
+ printasprite();
+skipsprite:
+ bx = pop();
+ cx = pop();
+ _add(bx, (32));
+ if (--cx)
+ goto prtspriteloop;
+ cx = pop();
+ _inc(cx);
+ _cmp(cx, 7);
+ if (!flags.z())
+ goto priorityloop;
+}
+
+void DreamGenContext::printasprite() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ si = bx;
+ ds = es.word(si+6);
+ al = es.byte(si+11);
+ ah = 0;
+ _cmp(al, 220);
+ if (flags.c())
+ goto notnegative1;
+ ah = 255;
+notnegative1:
+ bx = ax;
+ _add(bx, data.word(kMapady));
+ al = es.byte(si+10);
+ ah = 0;
+ _cmp(al, 220);
+ if (flags.c())
+ goto notnegative2;
+ ah = 255;
+notnegative2:
+ di = ax;
+ _add(di, data.word(kMapadx));
+ al = es.byte(si+15);
+ ah = 0;
+ _cmp(es.byte(si+30), 0);
+ if (flags.z())
+ goto steadyframe;
+ ah = 8;
+steadyframe:
+ _cmp(data.byte(kPriority), 6);
+ if (!flags.z())
+ goto notquickp;
+notquickp:
+ showframe();
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::checkone() {
+ STACK_CHECK;
+ push(cx);
+ al = ch;
+ ah = 0;
+ cl = 4;
+ _shr(ax, cl);
+ dl = al;
+ cx = pop();
+ al = cl;
+ ah = 0;
+ cl = 4;
+ _shr(ax, cl);
+ ah = dl;
+ push(ax);
+ ch = 0;
+ cl = al;
+ push(cx);
+ al = ah;
+ ah = 0;
+ cx = 11;
+ _mul(cx);
+ cx = pop();
+ _add(ax, cx);
+ cx = 3;
+ _mul(cx);
+ si = ax;
+ ds = data.word(kBuffers);
+ _add(si, (0+(228*13)+32+60+(32*32)));
+ _lodsw();
+ cx = ax;
+ _lodsb();
+ dx = pop();
+}
+
+void DreamGenContext::findsource() {
+ STACK_CHECK;
+ ax = data.word(kCurrentframe);
+ _cmp(ax, 160);
+ if (!flags.c())
+ goto over1000;
+ ds = data.word(kReel1);
+ data.word(kTakeoff) = 0;
+ return;
+over1000:
+ _cmp(ax, 320);
+ if (!flags.c())
+ goto over1001;
+ ds = data.word(kReel2);
+ data.word(kTakeoff) = 160;
+ return;
+over1001:
+ ds = data.word(kReel3);
+ data.word(kTakeoff) = 320;
+}
+
+void DreamGenContext::initman() {
+ STACK_CHECK;
+ al = data.byte(kRyanx);
+ ah = data.byte(kRyany);
+ si = ax;
+ cx = 49464;
+ dx = data.word(kMainsprites);
+ di = 0;
+ makesprite();
+ es.byte(bx+23) = 4;
+ es.byte(bx+22) = 0;
+ es.byte(bx+29) = 0;
+}
+
+void DreamGenContext::mainman() {
+ STACK_CHECK;
+ _cmp(data.byte(kResetmanxy), 1);
+ if (!flags.z())
+ goto notinnewroom;
+ data.byte(kResetmanxy) = 0;
+ al = data.byte(kRyanx);
+ ah = data.byte(kRyany);
+ es.word(bx+10) = ax;
+ es.byte(bx+29) = 0;
+ goto executewalk;
+notinnewroom:
+ _dec(es.byte(bx+22));
+ _cmp(es.byte(bx+22), -1);
+ if (flags.z())
+ goto executewalk;
+ return;
+executewalk:
+ es.byte(bx+22) = 0;
+ al = data.byte(kTurntoface);
+ _cmp(al, data.byte(kFacing));
+ if (flags.z())
+ goto facingok;
+ aboutturn();
+ goto notwalk;
+facingok:
+ _cmp(data.byte(kTurndirection), 0);
+ if (flags.z())
+ goto alreadyturned;
+ _cmp(data.byte(kLinepointer), 254);
+ if (!flags.z())
+ goto alreadyturned;
+ data.byte(kReasseschanges) = 1;
+ al = data.byte(kFacing);
+ _cmp(al, data.byte(kLeavedirection));
+ if (!flags.z())
+ goto alreadyturned;
+ checkforexit();
+alreadyturned:
+ data.byte(kTurndirection) = 0;
+ _cmp(data.byte(kLinepointer), 254);
+ if (!flags.z())
+ goto walkman;
+ es.byte(bx+29) = 0;
+ goto notwalk;
+walkman:
+ al = es.byte(bx+29);
+ _inc(al);
+ _cmp(al, 11);
+ if (!flags.z())
+ goto notanimend1;
+ al = 1;
+notanimend1:
+ es.byte(bx+29) = al;
+ walking();
+ _cmp(data.byte(kLinepointer), 254);
+ if (flags.z())
+ goto afterwalk;
+ al = data.byte(kFacing);
+ _and(al, 1);
+ if (flags.z())
+ goto isdouble;
+ al = es.byte(bx+29);
+ _cmp(al, 2);
+ if (flags.z())
+ goto afterwalk;
+ _cmp(al, 7);
+ if (flags.z())
+ goto afterwalk;
+isdouble:
+ walking();
+afterwalk:
+ _cmp(data.byte(kLinepointer), 254);
+ if (!flags.z())
+ goto notwalk;
+ al = data.byte(kTurntoface);
+ _cmp(al, data.byte(kFacing));
+ if (!flags.z())
+ goto notwalk;
+ data.byte(kReasseschanges) = 1;
+ al = data.byte(kFacing);
+ _cmp(al, data.byte(kLeavedirection));
+ if (!flags.z())
+ goto notwalk;
+ checkforexit();
+notwalk:
+ al = data.byte(kFacing);
+ ah = 0;
+ di = 1105;
+ _add(di, ax);
+ al = cs.byte(di);
+ _add(al, es.byte(bx+29));
+ es.byte(bx+15) = al;
+ ax = es.word(bx+10);
+ data.byte(kRyanx) = al;
+ data.byte(kRyany) = ah;
+}
+
+void DreamGenContext::aboutturn() {
+ STACK_CHECK;
+ _cmp(data.byte(kTurndirection), 1);
+ if (flags.z())
+ goto incdir;
+ _cmp(data.byte(kTurndirection), -1);
+ if (flags.z())
+ goto decdir;
+ al = data.byte(kFacing);
+ _sub(al, data.byte(kTurntoface));
+ if (!flags.c())
+ goto higher;
+ _neg(al);
+ _cmp(al, 4);
+ if (!flags.c())
+ goto decdir;
+ goto incdir;
+higher:
+ _cmp(al, 4);
+ if (!flags.c())
+ goto incdir;
+ goto decdir;
+incdir:
+ data.byte(kTurndirection) = 1;
+ al = data.byte(kFacing);
+ _inc(al);
+ _and(al, 7);
+ data.byte(kFacing) = al;
+ es.byte(bx+29) = 0;
+ return;
+decdir:
+ data.byte(kTurndirection) = -1;
+ al = data.byte(kFacing);
+ _dec(al);
+ _and(al, 7);
+ data.byte(kFacing) = al;
+ es.byte(bx+29) = 0;
+}
+
+void DreamGenContext::walking() {
+ STACK_CHECK;
+ _cmp(data.byte(kLinedirection), 0);
+ if (flags.z())
+ goto normalwalk;
+ al = data.byte(kLinepointer);
+ _dec(al);
+ data.byte(kLinepointer) = al;
+ _cmp(al, 200);
+ if (!flags.c())
+ goto endofline;
+ goto continuewalk;
+normalwalk:
+ al = data.byte(kLinepointer);
+ _inc(al);
+ data.byte(kLinepointer) = al;
+ _cmp(al, data.byte(kLinelength));
+ if (!flags.c())
+ goto endofline;
+continuewalk:
+ ah = 0;
+ _add(ax, ax);
+ push(es);
+ push(bx);
+ dx = data;
+ es = dx;
+ bx = 8173;
+ _add(bx, ax);
+ ax = es.word(bx);
+ bx = pop();
+ es = pop();
+ es.word(bx+10) = ax;
+ return;
+endofline:
+ data.byte(kLinepointer) = 254;
+ al = data.byte(kDestination);
+ data.byte(kManspath) = al;
+ _cmp(al, data.byte(kFinaldest));
+ if (flags.z())
+ goto finishedwalk;
+ al = data.byte(kFinaldest);
+ data.byte(kDestination) = al;
+ push(es);
+ push(bx);
+ autosetwalk();
+ bx = pop();
+ es = pop();
+ return;
+finishedwalk:
+ facerightway();
+}
+
+void DreamGenContext::facerightway() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ getroomspaths();
+ al = data.byte(kManspath);
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = es.byte(bx+7);
+ data.byte(kTurntoface) = al;
+ data.byte(kLeavedirection) = al;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::checkforexit() {
+ STACK_CHECK;
+ cl = data.byte(kRyanx);
+ _add(cl, 12);
+ ch = data.byte(kRyany);
+ _add(ch, 12);
+ checkone();
+ data.byte(kLastflag) = cl;
+ data.byte(kLastflagex) = ch;
+ data.byte(kFlagx) = dl;
+ data.byte(kFlagy) = dh;
+ al = data.byte(kLastflag);
+ _test(al, 64);
+ if (flags.z())
+ goto notnewdirect;
+ al = data.byte(kLastflagex);
+ data.byte(kAutolocation) = al;
+ return;
+notnewdirect:
+ _test(al, 32);
+ if (flags.z())
+ goto notleave;
+ push(es);
+ push(bx);
+ _cmp(data.byte(kReallocation), 2);
+ if (!flags.z())
+ goto notlouis;
+ bl = 0;
+ push(bx);
+ al = 'W';
+ ah = 'E';
+ cl = 'T';
+ ch = 'A';
+ isryanholding();
+ bx = pop();
+ if (flags.z())
+ goto noshoe1;
+ _inc(bl);
+noshoe1:
+ push(bx);
+ al = 'W';
+ ah = 'E';
+ cl = 'T';
+ ch = 'B';
+ isryanholding();
+ bx = pop();
+ if (flags.z())
+ goto noshoe2;
+ _inc(bl);
+noshoe2:
+ _cmp(bl, 2);
+ if (flags.z())
+ goto notlouis;
+ al = 42;
+ _cmp(bl, 0);
+ if (flags.z())
+ goto notravmessage;
+ _inc(al);
+notravmessage:
+ cx = 80;
+ dx = 10;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+ al = data.byte(kFacing);
+ _add(al, 4);
+ _and(al, 7);
+ data.byte(kTurntoface) = al;
+ bx = pop();
+ es = pop();
+ return;
+notlouis:
+ bx = pop();
+ es = pop();
+ data.byte(kNeedtotravel) = 1;
+ return;
+notleave:
+ _test(al, 4);
+ if (flags.z())
+ goto notaleft;
+ adjustleft();
+ return;
+notaleft:
+ _test(al, 2);
+ if (flags.z())
+ goto notaright;
+ adjustright();
+ return;
+notaright:
+ _test(al, 8);
+ if (flags.z())
+ goto notadown;
+ adjustdown();
+ return;
+notadown:
+ _test(al, 16);
+ if (flags.z())
+ return /* (notanup) */;
+ adjustup();
+}
+
+void DreamGenContext::adjustdown() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ _add(data.byte(kMapy), 10);
+ al = data.byte(kLastflagex);
+ cl = 16;
+ _mul(cl);
+ es.byte(bx+11) = al;
+ data.byte(kNowinnewroom) = 1;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::adjustup() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ _sub(data.byte(kMapy), 10);
+ al = data.byte(kLastflagex);
+ cl = 16;
+ _mul(cl);
+ es.byte(bx+11) = al;
+ data.byte(kNowinnewroom) = 1;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::adjustleft() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ data.byte(kLastflag) = 0;
+ _sub(data.byte(kMapx), 11);
+ al = data.byte(kLastflagex);
+ cl = 16;
+ _mul(cl);
+ es.byte(bx+10) = al;
+ data.byte(kNowinnewroom) = 1;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::adjustright() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ _add(data.byte(kMapx), 11);
+ al = data.byte(kLastflagex);
+ cl = 16;
+ _mul(cl);
+ _sub(al, 2);
+ es.byte(bx+10) = al;
+ data.byte(kNowinnewroom) = 1;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::reminders() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 24);
+ if (!flags.z())
+ return /* (notinedenslift) */;
+ _cmp(data.byte(kMapx), 44);
+ if (!flags.z())
+ return /* (notinedenslift) */;
+ _cmp(data.byte(kProgresspoints), 0);
+ if (!flags.z())
+ return /* (notfirst) */;
+ al = 'D';
+ ah = 'K';
+ cl = 'E';
+ ch = 'Y';
+ isryanholding();
+ if (flags.z())
+ goto forgotone;
+ al = 'C';
+ ah = 'S';
+ cl = 'H';
+ ch = 'R';
+ findexobject();
+ _cmp(al, (114));
+ if (flags.z())
+ goto forgotone;
+ ax = es.word(bx+2);
+ _cmp(al, 4);
+ if (!flags.z())
+ goto forgotone;
+ _cmp(ah, 255);
+ if (flags.z())
+ goto havegotcard;
+ cl = 'P';
+ ch = 'U';
+ dl = 'R';
+ dh = 'S';
+ _xchg(al, ah);
+ compare();
+ if (!flags.z())
+ goto forgotone;
+havegotcard:
+ _inc(data.byte(kProgresspoints));
+ return;
+forgotone:
+ al = 50;
+ bl = 54;
+ bh = 70;
+ cx = 48;
+ dx = 8;
+ setuptimeduse();
+}
+
+void DreamGenContext::initrain() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30));
+ bx = 1113;
+checkmorerain:
+ al = cs.byte(bx);
+ _cmp(al, 255);
+ if (flags.z())
+ goto finishinitrain;
+ _cmp(al, data.byte(kReallocation));
+ if (!flags.z())
+ goto checkrain;
+ al = cs.byte(bx+1);
+ _cmp(al, data.byte(kMapx));
+ if (!flags.z())
+ goto checkrain;
+ al = cs.byte(bx+2);
+ _cmp(al, data.byte(kMapy));
+ if (!flags.z())
+ goto checkrain;
+ al = cs.byte(bx+3);
+ data.byte(kRainspace) = al;
+ goto dorain;
+checkrain:
+ _add(bx, 4);
+ goto checkmorerain;
+dorain:
+ cx = 4;
+initraintop:
+ randomnumber();
+ _and(al, 31);
+ _add(al, 3);
+ _cmp(al, data.byte(kRainspace));
+ if (!flags.c())
+ goto initraintop;
+ _add(cl, al);
+ _cmp(cl, data.byte(kMapxsize));
+ if (!flags.c())
+ goto initrainside;
+ push(cx);
+ splitintolines();
+ cx = pop();
+ goto initraintop;
+initrainside:
+ cl = data.byte(kMapxsize);
+ _dec(cl);
+initrainside2:
+ randomnumber();
+ _and(al, 31);
+ _add(al, 3);
+ _cmp(al, data.byte(kRainspace));
+ if (!flags.c())
+ goto initrainside2;
+ _add(ch, al);
+ _cmp(ch, data.byte(kMapysize));
+ if (!flags.c())
+ goto finishinitrain;
+ push(cx);
+ splitintolines();
+ cx = pop();
+ goto initrainside2;
+finishinitrain:
+ al = 255;
+ _stosb();
+}
+
+void DreamGenContext::splitintolines() {
+ STACK_CHECK;
+lookforlinestart:
+ getblockofpixel();
+ _cmp(al, 0);
+ if (!flags.z())
+ goto foundlinestart;
+ _dec(cl);
+ _inc(ch);
+ _cmp(cl, 0);
+ if (flags.z())
+ return /* (endofthisline) */;
+ _cmp(ch, data.byte(kMapysize));
+ if (!flags.c())
+ return /* (endofthisline) */;
+ goto lookforlinestart;
+foundlinestart:
+ es.word(di) = cx;
+ bh = 1;
+lookforlineend:
+ getblockofpixel();
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundlineend;
+ _dec(cl);
+ _inc(ch);
+ _cmp(cl, 0);
+ if (flags.z())
+ goto foundlineend;
+ _cmp(ch, data.byte(kMapysize));
+ if (!flags.c())
+ goto foundlineend;
+ _inc(bh);
+ goto lookforlineend;
+foundlineend:
+ push(cx);
+ es.byte(di+2) = bh;
+ randomnumber();
+ es.byte(di+3) = al;
+ randomnumber();
+ es.byte(di+4) = al;
+ randomnumber();
+ _and(al, 3);
+ _add(al, 4);
+ es.byte(di+5) = al;
+ _add(di, 6);
+ cx = pop();
+ _cmp(cl, 0);
+ if (flags.z())
+ return /* (endofthisline) */;
+ _cmp(ch, data.byte(kMapysize));
+ if (!flags.c())
+ return /* (endofthisline) */;
+ goto lookforlinestart;
+}
+
+void DreamGenContext::getblockofpixel() {
+ STACK_CHECK;
+ push(cx);
+ push(es);
+ push(di);
+ ax = data.word(kMapxstart);
+ _add(cl, al);
+ ax = data.word(kMapystart);
+ _add(ch, al);
+ checkone();
+ _and(cl, 1);
+ if (!flags.z())
+ goto failrain;
+ di = pop();
+ es = pop();
+ cx = pop();
+ return;
+failrain:
+ di = pop();
+ es = pop();
+ cx = pop();
+ al = 0;
+}
+
+void DreamGenContext::showrain() {
+ STACK_CHECK;
+ ds = data.word(kMainsprites);
+ si = 6*58;
+ ax = ds.word(si+2);
+ si = ax;
+ _add(si, 2080);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30));
+ es = data.word(kBuffers);
+ _cmp(es.byte(bx), 255);
+ if (flags.z())
+ return /* (nothunder) */;
+morerain:
+ es = data.word(kBuffers);
+ _cmp(es.byte(bx), 255);
+ if (flags.z())
+ goto finishrain;
+ al = es.byte(bx+1);
+ ah = 0;
+ _add(ax, data.word(kMapady));
+ _add(ax, data.word(kMapystart));
+ cx = 320;
+ _mul(cx);
+ cl = es.byte(bx);
+ ch = 0;
+ _add(ax, cx);
+ _add(ax, data.word(kMapadx));
+ _add(ax, data.word(kMapxstart));
+ di = ax;
+ cl = es.byte(bx+2);
+ ch = 0;
+ ax = es.word(bx+3);
+ dl = es.byte(bx+5);
+ dh = 0;
+ _sub(ax, dx);
+ _and(ax, 511);
+ es.word(bx+3) = ax;
+ _add(bx, 6);
+ push(si);
+ _add(si, ax);
+ es = data.word(kWorkspace);
+ ah = 0;
+ dx = 320-2;
+rainloop:
+ _lodsb();
+ _cmp(al, ah);
+ if (flags.z())
+ goto noplot;
+ _stosb();
+ _add(di, dx);
+ if (--cx)
+ goto rainloop;
+ si = pop();
+ goto morerain;
+noplot:
+ _add(di, 320-1);
+ if (--cx)
+ goto rainloop;
+ si = pop();
+ goto morerain;
+finishrain:
+ _cmp(data.word(kCh1blockstocopy), 0);
+ if (!flags.z())
+ return /* (nothunder) */;
+ _cmp(data.byte(kReallocation), 2);
+ if (!flags.z())
+ goto notlouisthund;
+ _cmp(data.byte(kBeenmugged), 1);
+ if (!flags.z())
+ return /* (nothunder) */;
+notlouisthund:
+ _cmp(data.byte(kReallocation), 55);
+ if (flags.z())
+ return /* (nothunder) */;
+ randomnum1();
+ _cmp(al, 1);
+ if (!flags.c())
+ return /* (nothunder) */;
+ al = 7;
+ _cmp(data.byte(kCh0playing), 6);
+ if (flags.z())
+ goto isthunder1;
+ al = 4;
+isthunder1:
+ playchannel1();
+}
+
+void DreamGenContext::backobject() {
+ STACK_CHECK;
+ ds = data.word(kSetdat);
+ di = es.word(bx+20);
+ al = es.byte(bx+18);
+ _cmp(al, 0);
+ if (flags.z())
+ goto _tmp48z;
+ _dec(al);
+ es.byte(bx+18) = al;
+ return /* (finishback) */;
+_tmp48z:
+ al = ds.byte(di+7);
+ es.byte(bx+18) = al;
+ al = ds.byte(di+8);
+ _cmp(al, 6);
+ if (!flags.z())
+ goto notwidedoor;
+ widedoor();
+ return /* (finishback) */;
+notwidedoor:
+ _cmp(al, 5);
+ if (!flags.z())
+ goto notrandom;
+ random();
+ return /* (finishback) */;
+notrandom:
+ _cmp(al, 4);
+ if (!flags.z())
+ goto notlockdoor;
+ lockeddoorway();
+ return /* (finishback) */;
+notlockdoor:
+ _cmp(al, 3);
+ if (!flags.z())
+ goto notlift;
+ liftsprite();
+ return /* (finishback) */;
+notlift:
+ _cmp(al, 2);
+ if (!flags.z())
+ goto notdoor;
+ doorway();
+ return /* (finishback) */;
+notdoor:
+ _cmp(al, 1);
+ if (!flags.z())
+ goto steadyob;
+ constant();
+ return /* (finishback) */;
+steadyob:
+ steady();
+}
+
+void DreamGenContext::liftsprite() {
+ STACK_CHECK;
+ al = data.byte(kLiftflag);
+ _cmp(al, 0);
+ if (flags.z())
+ goto liftclosed;
+ _cmp(al, 1);
+ if (flags.z())
+ goto liftopen;
+ _cmp(al, 3);
+ if (flags.z())
+ goto openlift;
+ al = es.byte(bx+19);
+ _cmp(al, 0);
+ if (flags.z())
+ goto finishclose;
+ _dec(al);
+ _cmp(al, 11);
+ if (!flags.z())
+ goto pokelift;
+ push(ax);
+ al = 3;
+ liftnoise();
+ ax = pop();
+ goto pokelift;
+finishclose:
+ data.byte(kLiftflag) = 0;
+ return;
+openlift:
+ al = es.byte(bx+19);
+ _cmp(al, 12);
+ if (flags.z())
+ goto endoflist;
+ _inc(al);
+ _cmp(al, 1);
+ if (!flags.z())
+ goto pokelift;
+ push(ax);
+ al = 2;
+ liftnoise();
+ ax = pop();
+pokelift:
+ es.byte(bx+19) = al;
+ ah = 0;
+ push(di);
+ _add(di, ax);
+ al = ds.byte(di+18);
+ di = pop();
+ es.byte(bx+15) = al;
+ ds.byte(di+17) = al;
+ return;
+endoflist:
+ data.byte(kLiftflag) = 1;
+ return;
+liftopen:
+ al = data.byte(kLiftpath);
+ push(es);
+ push(bx);
+ turnpathon();
+ bx = pop();
+ es = pop();
+ _cmp(data.byte(kCounttoclose), 0);
+ if (flags.z())
+ goto nocountclose;
+ _dec(data.byte(kCounttoclose));
+ _cmp(data.byte(kCounttoclose), 0);
+ if (!flags.z())
+ goto nocountclose;
+ data.byte(kLiftflag) = 2;
+nocountclose:
+ al = 12;
+ goto pokelift;
+liftclosed:
+ al = data.byte(kLiftpath);
+ push(es);
+ push(bx);
+ turnpathoff();
+ bx = pop();
+ es = pop();
+ _cmp(data.byte(kCounttoopen), 0);
+ if (flags.z())
+ goto nocountopen;
+ _dec(data.byte(kCounttoopen));
+ _cmp(data.byte(kCounttoopen), 0);
+ if (!flags.z())
+ goto nocountopen;
+ data.byte(kLiftflag) = 3;
+nocountopen:
+ al = 0;
+ goto pokelift;
+}
+
+void DreamGenContext::liftnoise() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 5);
+ if (flags.z())
+ goto hissnoise;
+ _cmp(data.byte(kReallocation), 21);
+ if (flags.z())
+ goto hissnoise;
+ playchannel1();
+ return;
+hissnoise:
+ al = 13;
+ playchannel1();
+}
+
+void DreamGenContext::random() {
+ STACK_CHECK;
+ randomnum1();
+ push(di);
+ _and(ax, 7);
+ _add(di, 18);
+ _add(di, ax);
+ al = ds.byte(di);
+ di = pop();
+ es.byte(bx+15) = al;
+}
+
+void DreamGenContext::steady() {
+ STACK_CHECK;
+ al = ds.byte(di+18);
+ ds.byte(di+17) = al;
+ es.byte(bx+15) = al;
+}
+
+void DreamGenContext::constant() {
+ STACK_CHECK;
+ _inc(es.byte(bx+19));
+ cl = es.byte(bx+19);
+ ch = 0;
+ _add(di, cx);
+ _cmp(ds.byte(di+18), 255);
+ if (!flags.z())
+ goto gotconst;
+ _sub(di, cx);
+ cx = 0;
+ es.byte(bx+19) = cl;
+gotconst:
+ al = ds.byte(di+18);
+ _sub(di, cx);
+ es.byte(bx+15) = al;
+ ds.byte(di+17) = al;
+}
+
+void DreamGenContext::doorway() {
+ STACK_CHECK;
+ data.byte(kDoorcheck1) = -24;
+ data.byte(kDoorcheck2) = 10;
+ data.byte(kDoorcheck3) = -30;
+ data.byte(kDoorcheck4) = 10;
+ dodoor();
+}
+
+void DreamGenContext::widedoor() {
+ STACK_CHECK;
+ data.byte(kDoorcheck1) = -24;
+ data.byte(kDoorcheck2) = 24;
+ data.byte(kDoorcheck3) = -30;
+ data.byte(kDoorcheck4) = 24;
+ dodoor();
+}
+
+void DreamGenContext::dodoor() {
+ STACK_CHECK;
+ al = data.byte(kRyanx);
+ ah = data.byte(kRyany);
+ cl = es.byte(bx+10);
+ ch = es.byte(bx+11);
+ _cmp(al, cl);
+ if (!flags.c())
+ goto rtofdoor;
+ _sub(al, cl);
+ _cmp(al, data.byte(kDoorcheck1));
+ if (!flags.c())
+ goto upordown;
+ goto shutdoor;
+rtofdoor:
+ _sub(al, cl);
+ _cmp(al, data.byte(kDoorcheck2));
+ if (!flags.c())
+ goto shutdoor;
+upordown:
+ _cmp(ah, ch);
+ if (!flags.c())
+ goto botofdoor;
+ _sub(ah, ch);
+ _cmp(ah, data.byte(kDoorcheck3));
+ if (flags.c())
+ goto shutdoor;
+ goto opendoor;
+botofdoor:
+ _sub(ah, ch);
+ _cmp(ah, data.byte(kDoorcheck4));
+ if (!flags.c())
+ goto shutdoor;
+opendoor:
+ cl = es.byte(bx+19);
+ _cmp(data.byte(kThroughdoor), 1);
+ if (!flags.z())
+ goto notthrough;
+ _cmp(cl, 0);
+ if (!flags.z())
+ goto notthrough;
+ cl = 6;
+notthrough:
+ _inc(cl);
+ _cmp(cl, 1);
+ if (!flags.z())
+ goto notdoorsound2;
+ al = 0;
+ _cmp(data.byte(kReallocation), 5);
+ if (!flags.z())
+ goto nothoteldoor2;
+ al = 13;
+nothoteldoor2:
+ playchannel1();
+notdoorsound2:
+ ch = 0;
+ push(di);
+ _add(di, cx);
+ al = ds.byte(di+18);
+ _cmp(al, 255);
+ if (!flags.z())
+ goto atlast1;
+ _dec(di);
+ _dec(cl);
+atlast1:
+ es.byte(bx+19) = cl;
+ al = ds.byte(di+18);
+ di = pop();
+ es.byte(bx+15) = al;
+ ds.byte(di+17) = al;
+ data.byte(kThroughdoor) = 1;
+ return;
+shutdoor:
+ cl = es.byte(bx+19);
+ _cmp(cl, 5);
+ if (!flags.z())
+ goto notdoorsound1;
+ al = 1;
+ _cmp(data.byte(kReallocation), 5);
+ if (!flags.z())
+ goto nothoteldoor1;
+ al = 13;
+nothoteldoor1:
+ playchannel1();
+notdoorsound1:
+ _cmp(cl, 0);
+ if (flags.z())
+ goto atlast2;
+ _dec(cl);
+ es.byte(bx+19) = cl;
+atlast2:
+ ch = 0;
+ push(di);
+ _add(di, cx);
+ al = ds.byte(di+18);
+ di = pop();
+ es.byte(bx+15) = al;
+ ds.byte(di+17) = al;
+ _cmp(cl, 5);
+ if (!flags.z())
+ return /* (notnearly) */;
+ data.byte(kThroughdoor) = 0;
+}
+
+void DreamGenContext::lockeddoorway() {
+ STACK_CHECK;
+ al = data.byte(kRyanx);
+ ah = data.byte(kRyany);
+ cl = es.byte(bx+10);
+ ch = es.byte(bx+11);
+ _cmp(al, cl);
+ if (!flags.c())
+ goto rtofdoor2;
+ _sub(al, cl);
+ _cmp(al, -24);
+ if (!flags.c())
+ goto upordown2;
+ goto shutdoor2;
+rtofdoor2:
+ _sub(al, cl);
+ _cmp(al, 10);
+ if (!flags.c())
+ goto shutdoor2;
+upordown2:
+ _cmp(ah, ch);
+ if (!flags.c())
+ goto botofdoor2;
+ _sub(ah, ch);
+ _cmp(ah, -30);
+ if (flags.c())
+ goto shutdoor2;
+ goto opendoor2;
+botofdoor2:
+ _sub(ah, ch);
+ _cmp(ah, 12);
+ if (!flags.c())
+ goto shutdoor2;
+opendoor2:
+ _cmp(data.byte(kThroughdoor), 1);
+ if (flags.z())
+ goto mustbeopen;
+ _cmp(data.byte(kLockstatus), 1);
+ if (flags.z())
+ goto shutdoor;
+mustbeopen:
+ cl = es.byte(bx+19);
+ _cmp(cl, 1);
+ if (!flags.z())
+ goto notdoorsound4;
+ al = 0;
+ playchannel1();
+notdoorsound4:
+ _cmp(cl, 6);
+ if (!flags.z())
+ goto noturnonyet;
+ al = data.byte(kDoorpath);
+ push(es);
+ push(bx);
+ turnpathon();
+ bx = pop();
+ es = pop();
+noturnonyet:
+ cl = es.byte(bx+19);
+ _cmp(data.byte(kThroughdoor), 1);
+ if (!flags.z())
+ goto notthrough2;
+ _cmp(cl, 0);
+ if (!flags.z())
+ goto notthrough2;
+ cl = 6;
+notthrough2:
+ _inc(cl);
+ ch = 0;
+ push(di);
+ _add(di, cx);
+ al = ds.byte(di+18);
+ _cmp(al, 255);
+ if (!flags.z())
+ goto atlast3;
+ _dec(di);
+ _dec(cl);
+atlast3:
+ es.byte(bx+19) = cl;
+ al = ds.byte(di+18);
+ di = pop();
+ es.byte(bx+15) = al;
+ ds.byte(di+17) = al;
+ _cmp(cl, 5);
+ if (!flags.z())
+ return /* (justshutting) */;
+ data.byte(kThroughdoor) = 1;
+ return;
+shutdoor2:
+ cl = es.byte(bx+19);
+ _cmp(cl, 5);
+ if (!flags.z())
+ goto notdoorsound3;
+ al = 1;
+ playchannel1();
+notdoorsound3:
+ _cmp(cl, 0);
+ if (flags.z())
+ goto atlast4;
+ _dec(cl);
+ es.byte(bx+19) = cl;
+atlast4:
+ ch = 0;
+ data.byte(kThroughdoor) = 0;
+ push(di);
+ _add(di, cx);
+ al = ds.byte(di+18);
+ di = pop();
+ es.byte(bx+15) = al;
+ ds.byte(di+17) = al;
+ _cmp(cl, 0);
+ if (!flags.z())
+ return /* (notlocky) */;
+ al = data.byte(kDoorpath);
+ push(es);
+ push(bx);
+ turnpathoff();
+ bx = pop();
+ es = pop();
+ data.byte(kLockstatus) = 1;
+ return;
+/*continuing to unbounded code: shutdoor from dodoor:60-87*/
+shutdoor:
+ cl = es.byte(bx+19);
+ _cmp(cl, 5);
+ if (!flags.z())
+ goto notdoorsound1;
+ al = 1;
+ _cmp(data.byte(kReallocation), 5);
+ if (!flags.z())
+ goto nothoteldoor1;
+ al = 13;
+nothoteldoor1:
+ playchannel1();
+notdoorsound1:
+ _cmp(cl, 0);
+ if (flags.z())
+ goto atlast2;
+ _dec(cl);
+ es.byte(bx+19) = cl;
+atlast2:
+ ch = 0;
+ push(di);
+ _add(di, cx);
+ al = ds.byte(di+18);
+ di = pop();
+ es.byte(bx+15) = al;
+ ds.byte(di+17) = al;
+ _cmp(cl, 5);
+ if (!flags.z())
+ return /* (notnearly) */;
+ data.byte(kThroughdoor) = 0;
+}
+
+void DreamGenContext::updatepeople() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5));
+ data.word(kListpos) = di;
+ cx = 12*5;
+ al = 255;
+ _stosb(cx, true);
+ _inc(data.word(kMaintimer));
+ es = cs;
+ bx = 534;
+ di = 991;
+updateloop:
+ al = es.byte(bx);
+ _cmp(al, 255);
+ if (flags.z())
+ return /* (endupdate) */;
+ _cmp(al, data.byte(kReallocation));
+ if (!flags.z())
+ goto notinthisroom;
+ cx = es.word(bx+1);
+ _cmp(cl, data.byte(kMapx));
+ if (!flags.z())
+ goto notinthisroom;
+ _cmp(ch, data.byte(kMapy));
+ if (!flags.z())
+ goto notinthisroom;
+ push(di);
+ ax = cs.word(di);
+ __dispatch_call(ax);
+ di = pop();
+notinthisroom:
+ _add(bx, 8);
+ _add(di, 2);
+ goto updateloop;
+}
+
+void DreamGenContext::getreelframeax() {
+ STACK_CHECK;
+ push(ds);
+ data.word(kCurrentframe) = ax;
+ findsource();
+ es = ds;
+ ds = pop();
+ ax = data.word(kCurrentframe);
+ _sub(ax, data.word(kTakeoff));
+ _add(ax, ax);
+ cx = ax;
+ _add(ax, ax);
+ _add(ax, cx);
+ bx = ax;
+}
+
+void DreamGenContext::reelsonscreen() {
+ STACK_CHECK;
+ reconstruct();
+ updatepeople();
+ watchreel();
+ showrain();
+ usetimedtext();
+}
+
+void DreamGenContext::plotreel() {
+ STACK_CHECK;
+ getreelstart();
+retryreel:
+ push(es);
+ push(si);
+ ax = es.word(si+2);
+ _cmp(al, 220);
+ if (flags.c())
+ goto normalreel;
+ _cmp(al, 255);
+ if (flags.z())
+ goto normalreel;
+ dealwithspecial();
+ _inc(data.word(kReelpointer));
+ si = pop();
+ es = pop();
+ _add(si, 40);
+ goto retryreel;
+normalreel:
+ cx = 8;
+plotloop:
+ push(cx);
+ push(es);
+ push(si);
+ ax = es.word(si);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ goto notplot;
+ showreelframe();
+notplot:
+ si = pop();
+ es = pop();
+ cx = pop();
+ _add(si, 5);
+ if (--cx)
+ goto plotloop;
+ soundonreels();
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::soundonreels() {
+ STACK_CHECK;
+ bl = data.byte(kReallocation);
+ _add(bl, bl);
+ _xor(bh, bh);
+ _add(bx, 1214);
+ si = cs.word(bx);
+reelsoundloop:
+ al = cs.byte(si);
+ _cmp(al, 255);
+ if (flags.z())
+ goto endreelsound;
+ ax = cs.word(si+1);
+ _cmp(ax, data.word(kReelpointer));
+ if (!flags.z())
+ goto skipreelsound;
+ _cmp(ax, data.word(kLastsoundreel));
+ if (flags.z())
+ goto skipreelsound;
+ data.word(kLastsoundreel) = ax;
+ al = cs.byte(si);
+ _cmp(al, 64);
+ if (flags.c())
+ { playchannel1(); return; };
+ _cmp(al, 128);
+ if (flags.c())
+ goto channel0once;
+ _and(al, 63);
+ ah = 255;
+ { playchannel0(); return; };
+channel0once:
+ _and(al, 63);
+ ah = 0;
+ { playchannel0(); return; };
+skipreelsound:
+ _add(si, 3);
+ goto reelsoundloop;
+endreelsound:
+ ax = data.word(kLastsoundreel);
+ _cmp(ax, data.word(kReelpointer));
+ if (flags.z())
+ return /* (nochange2) */;
+ data.word(kLastsoundreel) = -1;
+}
+
+void DreamGenContext::reconstruct() {
+ STACK_CHECK;
+ _cmp(data.byte(kHavedoneobs), 0);
+ if (flags.z())
+ return /* (noneedtorecon) */;
+ data.byte(kNewobs) = 1;
+ drawfloor();
+ spriteupdate();
+ printsprites();
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto notfudge;
+ _cmp(data.byte(kReallocation), 20);
+ if (!flags.z())
+ goto notfudge;
+ undertextline();
+notfudge:
+ data.byte(kHavedoneobs) = 0;
+}
+
+void DreamGenContext::dealwithspecial() {
+ STACK_CHECK;
+ _sub(al, 220);
+ _cmp(al, 0);
+ if (!flags.z())
+ goto notplset;
+ al = ah;
+ placesetobject();
+ data.byte(kHavedoneobs) = 1;
+ return;
+notplset:
+ _cmp(al, 1);
+ if (!flags.z())
+ goto notremset;
+ al = ah;
+ removesetobject();
+ data.byte(kHavedoneobs) = 1;
+ return;
+notremset:
+ _cmp(al, 2);
+ if (!flags.z())
+ goto notplfree;
+ al = ah;
+ placefreeobject();
+ data.byte(kHavedoneobs) = 1;
+ return;
+notplfree:
+ _cmp(al, 3);
+ if (!flags.z())
+ goto notremfree;
+ al = ah;
+ removefreeobject();
+ data.byte(kHavedoneobs) = 1;
+ return;
+notremfree:
+ _cmp(al, 4);
+ if (!flags.z())
+ goto notryanoff;
+ switchryanoff();
+ return;
+notryanoff:
+ _cmp(al, 5);
+ if (!flags.z())
+ goto notryanon;
+ data.byte(kTurntoface) = ah;
+ data.byte(kFacing) = ah;
+ switchryanon();
+ return;
+notryanon:
+ _cmp(al, 6);
+ if (!flags.z())
+ goto notchangeloc;
+ data.byte(kNewlocation) = ah;
+ return;
+notchangeloc:
+ movemap();
+}
+
+void DreamGenContext::movemap() {
+ STACK_CHECK;
+ _cmp(ah, 32);
+ if (!flags.z())
+ goto notmapup2;
+ _sub(data.byte(kMapy), 20);
+ data.byte(kNowinnewroom) = 1;
+ return;
+notmapup2:
+ _cmp(ah, 16);
+ if (!flags.z())
+ goto notmapupspec;
+ _sub(data.byte(kMapy), 10);
+ data.byte(kNowinnewroom) = 1;
+ return;
+notmapupspec:
+ _cmp(ah, 8);
+ if (!flags.z())
+ goto notmapdownspec;
+ _add(data.byte(kMapy), 10);
+ data.byte(kNowinnewroom) = 1;
+ return;
+notmapdownspec:
+ _cmp(ah, 2);
+ if (!flags.z())
+ goto notmaprightspec;
+ _add(data.byte(kMapx), 11);
+ data.byte(kNowinnewroom) = 1;
+ return;
+notmaprightspec:
+ _sub(data.byte(kMapx), 11);
+ data.byte(kNowinnewroom) = 1;
+}
+
+void DreamGenContext::getreelstart() {
+ STACK_CHECK;
+ ax = data.word(kReelpointer);
+ cx = 40;
+ _mul(cx);
+ es = data.word(kReels);
+ si = ax;
+ _add(si, (0+(36*144)));
+}
+
+void DreamGenContext::showreelframe() {
+ STACK_CHECK;
+ al = es.byte(si+2);
+ ah = 0;
+ di = ax;
+ _add(di, data.word(kMapadx));
+ al = es.byte(si+3);
+ bx = ax;
+ _add(bx, data.word(kMapady));
+ ax = es.word(si);
+ data.word(kCurrentframe) = ax;
+ findsource();
+ ax = data.word(kCurrentframe);
+ _sub(ax, data.word(kTakeoff));
+ ah = 8;
+ showframe();
+}
+
+void DreamGenContext::deleverything() {
+ STACK_CHECK;
+ al = data.byte(kMapysize);
+ ah = 0;
+ _add(ax, data.word(kMapoffsety));
+ _cmp(ax, 182);
+ if (!flags.c())
+ goto bigroom;
+ maptopanel();
+ return;
+bigroom:
+ _sub(data.byte(kMapysize), 8);
+ maptopanel();
+ _add(data.byte(kMapysize), 8);
+}
+
+void DreamGenContext::dumpeverything() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40));
+dumpevery1:
+ ax = es.word(bx);
+ cx = es.word(bx+2);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ goto finishevery1;
+ _cmp(ax, es.word(bx+(40*5)));
+ if (!flags.z())
+ goto notskip1;
+ _cmp(cx, es.word(bx+(40*5)+2));
+ if (flags.z())
+ goto skip1;
+notskip1:
+ push(bx);
+ push(es);
+ push(ds);
+ bl = ah;
+ bh = 0;
+ ah = 0;
+ di = ax;
+ _add(di, data.word(kMapadx));
+ _add(bx, data.word(kMapady));
+ multidump();
+ ds = pop();
+ es = pop();
+ bx = pop();
+skip1:
+ _add(bx, 5);
+ goto dumpevery1;
+finishevery1:
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40))+(40*5);
+dumpevery2:
+ ax = es.word(bx);
+ cx = es.word(bx+2);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ return /* (finishevery2) */;
+ push(bx);
+ push(es);
+ push(ds);
+ bl = ah;
+ bh = 0;
+ ah = 0;
+ di = ax;
+ _add(di, data.word(kMapadx));
+ _add(bx, data.word(kMapady));
+ multidump();
+ ds = pop();
+ es = pop();
+ bx = pop();
+ _add(bx, 5);
+ goto dumpevery2;
+}
+
+void DreamGenContext::allocatework() {
+ STACK_CHECK;
+ bx = 0x1000;
+ allocatemem();
+ data.word(kWorkspace) = ax;
+}
+
+void DreamGenContext::loadpalfromiff() {
+ STACK_CHECK;
+ dx = 2481;
+ openfile();
+ cx = 2000;
+ ds = data.word(kMapstore);
+ dx = 0;
+ readfromfile();
+ closefile();
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768);
+ ds = data.word(kMapstore);
+ si = 0x30;
+ cx = 768;
+palloop:
+ _lodsb();
+ _shr(al, 1);
+ _shr(al, 1);
+ _cmp(data.byte(kBrightness), 1);
+ if (!flags.z())
+ goto nought;
+ _cmp(al, 0);
+ if (flags.z())
+ goto nought;
+ ah = al;
+ _shr(ah, 1);
+ _add(al, ah);
+ _shr(ah, 1);
+ _add(al, ah);
+ _cmp(al, 64);
+ if (flags.c())
+ goto nought;
+ al = 63;
+nought:
+ _stosb();
+ if (--cx)
+ goto palloop;
+}
+
+void DreamGenContext::paneltomap() {
+ STACK_CHECK;
+ di = data.word(kMapxstart);
+ _add(di, data.word(kMapadx));
+ bx = data.word(kMapystart);
+ _add(bx, data.word(kMapady));
+ ds = data.word(kMapstore);
+ si = 0;
+ cl = data.byte(kMapxsize);
+ ch = data.byte(kMapysize);
+ multiget();
+}
+
+void DreamGenContext::maptopanel() {
+ STACK_CHECK;
+ di = data.word(kMapxstart);
+ _add(di, data.word(kMapadx));
+ bx = data.word(kMapystart);
+ _add(bx, data.word(kMapady));
+ ds = data.word(kMapstore);
+ si = 0;
+ cl = data.byte(kMapxsize);
+ ch = data.byte(kMapysize);
+ multiput();
+}
+
+void DreamGenContext::dumpmap() {
+ STACK_CHECK;
+ di = data.word(kMapxstart);
+ _add(di, data.word(kMapadx));
+ bx = data.word(kMapystart);
+ _add(bx, data.word(kMapady));
+ cl = data.byte(kMapxsize);
+ ch = data.byte(kMapysize);
+ multidump();
+}
+
+void DreamGenContext::pixelcheckset() {
+ STACK_CHECK;
+ push(ax);
+ _sub(al, es.byte(bx));
+ _sub(ah, es.byte(bx+1));
+ push(es);
+ push(bx);
+ push(cx);
+ push(ax);
+ al = es.byte(bx+4);
+ getsetad();
+ al = es.byte(bx+17);
+ es = data.word(kSetframes);
+ bx = (0);
+ ah = 0;
+ cx = 6;
+ _mul(cx);
+ _add(bx, ax);
+ ax = pop();
+ push(ax);
+ al = ah;
+ ah = 0;
+ cl = es.byte(bx);
+ ch = 0;
+ _mul(cx);
+ cx = pop();
+ ch = 0;
+ _add(ax, cx);
+ _add(ax, es.word(bx+2));
+ bx = ax;
+ _add(bx, (0+2080));
+ al = es.byte(bx);
+ dl = al;
+ cx = pop();
+ bx = pop();
+ es = pop();
+ ax = pop();
+ _cmp(dl, 0);
+}
+
+void DreamGenContext::createpanel() {
+ STACK_CHECK;
+ di = 0;
+ bx = 8;
+ ds = data.word(kIcons2);
+ al = 0;
+ ah = 2;
+ showframe();
+ di = 160;
+ bx = 8;
+ ds = data.word(kIcons2);
+ al = 0;
+ ah = 2;
+ showframe();
+ di = 0;
+ bx = 104;
+ ds = data.word(kIcons2);
+ al = 0;
+ ah = 2;
+ showframe();
+ di = 160;
+ bx = 104;
+ ds = data.word(kIcons2);
+ al = 0;
+ ah = 2;
+ showframe();
+}
+
+void DreamGenContext::createpanel2() {
+ STACK_CHECK;
+ createpanel();
+ di = 0;
+ bx = 0;
+ ds = data.word(kIcons2);
+ al = 5;
+ ah = 2;
+ showframe();
+ di = 160;
+ bx = 0;
+ ds = data.word(kIcons2);
+ al = 5;
+ ah = 2;
+ showframe();
+}
+
+void DreamGenContext::clearwork() {
+ STACK_CHECK;
+ ax = 0x0;
+ es = data.word(kWorkspace);
+ di = 0;
+ cx = (200*320)/64;
+clearloop:
+ _stosw(32);
+ if (--cx)
+ goto clearloop;
+}
+
+void DreamGenContext::zoom() {
+ STACK_CHECK;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ return /* (inwatching) */;
+ _cmp(data.byte(kZoomon), 1);
+ if (flags.z())
+ goto zoomswitch;
+ return;
+zoomswitch:
+ _cmp(data.byte(kCommandtype), 199);
+ if (flags.c())
+ goto zoomit;
+ putunderzoom();
+ return;
+zoomit:
+ ax = data.word(kOldpointery);
+ _sub(ax, 9);
+ cx = (320);
+ _mul(cx);
+ _add(ax, data.word(kOldpointerx));
+ _sub(ax, 11);
+ si = ax;
+ ax = (132)+4;
+ cx = (320);
+ _mul(cx);
+ _add(ax, (8)+5);
+ di = ax;
+ es = data.word(kWorkspace);
+ ds = data.word(kWorkspace);
+ cx = 20;
+zoomloop:
+ push(cx);
+ cx = 23;
+zoomloop2:
+ _lodsb();
+ ah = al;
+ _stosw();
+ es.word(di+(320)-2) = ax;
+ if (--cx)
+ goto zoomloop2;
+ _add(si, (320)-23);
+ _add(di, (320)-46+(320));
+ cx = pop();
+ if (--cx)
+ goto zoomloop;
+ crosshair();
+ data.byte(kDidzoom) = 1;
+}
+
+void DreamGenContext::delthisone() {
+ STACK_CHECK;
+ push(ax);
+ push(ax);
+ al = ah;
+ ah = 0;
+ _add(ax, data.word(kMapady));
+ bx = (320);
+ _mul(bx);
+ bx = pop();
+ bh = 0;
+ _add(bx, data.word(kMapadx));
+ _add(ax, bx);
+ di = ax;
+ ax = pop();
+ push(ax);
+ al = ah;
+ ah = 0;
+ bx = 22*8;
+ _mul(bx);
+ bx = pop();
+ bh = 0;
+ _add(ax, bx);
+ si = ax;
+ es = data.word(kWorkspace);
+ ds = data.word(kMapstore);
+ dl = cl;
+ dh = 0;
+ ax = (320);
+ _sub(ax, dx);
+ _neg(dx);
+ _add(dx, 22*8);
+deloneloop:
+ push(cx);
+ ch = 0;
+ _movsb(cx, true);
+ cx = pop();
+ _add(di, ax);
+ _add(si, dx);
+ _dec(ch);
+ if (!flags.z())
+ goto deloneloop;
+}
+
+void DreamGenContext::doblocks() {
+ STACK_CHECK;
+ es = data.word(kWorkspace);
+ ax = data.word(kMapady);
+ cx = (320);
+ _mul(cx);
+ di = data.word(kMapadx);
+ _add(di, ax);
+ al = data.byte(kMapy);
+ ah = 0;
+ bx = (66);
+ _mul(bx);
+ bl = data.byte(kMapx);
+ bh = 0;
+ _add(ax, bx);
+ si = (0);
+ _add(si, ax);
+ cx = 10;
+loop120:
+ push(di);
+ push(cx);
+ cx = 11;
+loop124:
+ push(cx);
+ push(di);
+ ds = data.word(kMapdata);
+ _lodsb();
+ ds = data.word(kBackdrop);
+ push(si);
+ _cmp(al, 0);
+ if (flags.z())
+ goto zeroblock;
+ ah = al;
+ al = 0;
+ si = (0+192);
+ _add(si, ax);
+ bh = 14;
+ bh = 4;
+firstbitofblock:
+ _movsw(8);
+ _add(di, (320)-16);
+ _dec(bh);
+ if (!flags.z())
+ goto firstbitofblock;
+ bh = 12;
+loop125:
+ _movsw(8);
+ ax = 0x0dfdf;
+ _stosw(2);
+ _add(di, (320)-20);
+ _dec(bh);
+ if (!flags.z())
+ goto loop125;
+ _add(di, 4);
+ ax = 0x0dfdf;
+ _stosw(8);
+ _add(di, (320)-16);
+ _stosw(8);
+ _add(di, (320)-16);
+ _stosw(8);
+ _add(di, (320)-16);
+ _stosw(8);
+zeroblock:
+ si = pop();
+ di = pop();
+ cx = pop();
+ _add(di, 16);
+ if (--cx)
+ goto loop124;
+ _add(si, (66)-11);
+ cx = pop();
+ di = pop();
+ _add(di, (320)*16);
+ if (--cx)
+ goto loop120;
+}
+
+void DreamGenContext::showframe() {
+ STACK_CHECK;
+ push(dx);
+ push(ax);
+ cx = ax;
+ _and(cx, 511);
+ _add(cx, cx);
+ si = cx;
+ _add(cx, cx);
+ _add(si, cx);
+ _cmp(ds.word(si), 0);
+ if (!flags.z())
+ goto notblankshow;
+ ax = pop();
+ dx = pop();
+ cx = 0;
+ return;
+notblankshow:
+ _test(ah, 128);
+ if (!flags.z())
+ goto skipoffsets;
+ al = ds.byte(si+4);
+ ah = 0;
+ _add(di, ax);
+ al = ds.byte(si+5);
+ ah = 0;
+ _add(bx, ax);
+skipoffsets:
+ cx = ds.word(si+0);
+ ax = ds.word(si+2);
+ _add(ax, 2080);
+ si = ax;
+ ax = pop();
+ dx = pop();
+ _cmp(ah, 0);
+ if (flags.z())
+ goto noeffects;
+ _test(ah, 128);
+ if (flags.z())
+ goto notcentred;
+ push(ax);
+ al = cl;
+ ah = 0;
+ _shr(ax, 1);
+ _sub(di, ax);
+ al = ch;
+ ah = 0;
+ _shr(ax, 1);
+ _sub(bx, ax);
+ ax = pop();
+notcentred:
+ _test(ah, 64);
+ if (flags.z())
+ goto notdiffdest;
+ push(cx);
+ frameoutfx();
+ cx = pop();
+ return;
+notdiffdest:
+ _test(ah, 8);
+ if (flags.z())
+ goto notprintlist;
+ push(ax);
+ ax = di;
+ _sub(ax, data.word(kMapadx));
+ push(bx);
+ _sub(bx, data.word(kMapady));
+ ah = bl;
+ bx = pop();
+ ax = pop();
+notprintlist:
+ _test(ah, 4);
+ if (flags.z())
+ goto notflippedx;
+ dx = (320);
+ es = data.word(kWorkspace);
+ push(cx);
+ frameoutfx();
+ cx = pop();
+ return;
+notflippedx:
+ _test(ah, 2);
+ if (flags.z())
+ goto notnomask;
+ dx = (320);
+ es = data.word(kWorkspace);
+ push(cx);
+ frameoutnm();
+ cx = pop();
+ return;
+notnomask:
+ _test(ah, 32);
+ if (flags.z())
+ goto noeffects;
+ dx = (320);
+ es = data.word(kWorkspace);
+ push(cx);
+ frameoutbh();
+ cx = pop();
+ return;
+noeffects:
+ dx = (320);
+ es = data.word(kWorkspace);
+ push(cx);
+ frameoutv();
+ cx = pop();
+}
+
+void DreamGenContext::frameoutbh() {
+ STACK_CHECK;
+ push(dx);
+ ax = bx;
+ bx = dx;
+ _mul(bx);
+ _add(di, ax);
+ dx = pop();
+ push(cx);
+ ch = 0;
+ _sub(dx, cx);
+ cx = pop();
+bhloop2:
+ push(cx);
+ ch = 0;
+ ah = 255;
+bhloop1:
+ _cmp(es.byte(di), ah);
+ if (!flags.z())
+ goto nofill;
+ _movsb();
+ if (--cx)
+ goto bhloop1;
+ goto nextline;
+nofill:
+ _inc(di);
+ _inc(si);
+ if (--cx)
+ goto bhloop1;
+nextline:
+ _add(di, dx);
+ cx = pop();
+ _dec(ch);
+ if (!flags.z())
+ goto bhloop2;
+}
+
+void DreamGenContext::frameoutfx() {
+ STACK_CHECK;
+ push(dx);
+ ax = bx;
+ bx = dx;
+ _mul(bx);
+ _add(di, ax);
+ dx = pop();
+ push(cx);
+ ch = 0;
+ _add(dx, cx);
+ cx = pop();
+frameloopfx1:
+ push(cx);
+ ch = 0;
+frameloopfx2:
+ _lodsb();
+ _cmp(al, 0);
+ if (!flags.z())
+ goto backtosolidfx;
+backtootherfx:
+ _dec(di);
+ if (--cx)
+ goto frameloopfx2;
+ cx = pop();
+ _add(di, dx);
+ _dec(ch);
+ if (!flags.z())
+ goto frameloopfx1;
+ return;
+frameloopfx3:
+ _lodsb();
+ _cmp(al, 0);
+ if (flags.z())
+ goto backtootherfx;
+backtosolidfx:
+ es.byte(di) = al;
+ _dec(di);
+ if (--cx)
+ goto frameloopfx3;
+ cx = pop();
+ _add(di, dx);
+ _dec(ch);
+ if (!flags.z())
+ goto frameloopfx1;
+}
+
+void DreamGenContext::transferinv() {
+ STACK_CHECK;
+ di = data.word(kExframepos);
+ push(di);
+ al = data.byte(kExpos);
+ ah = 0;
+ bx = ax;
+ _add(ax, ax);
+ _add(ax, bx);
+ _inc(ax);
+ cx = 6;
+ _mul(cx);
+ es = data.word(kExtras);
+ bx = (0);
+ _add(bx, ax);
+ _add(di, (0+2080));
+ push(bx);
+ al = data.byte(kItemtotran);
+ ah = 0;
+ bx = ax;
+ _add(ax, ax);
+ _add(ax, bx);
+ _inc(ax);
+ cx = 6;
+ _mul(cx);
+ ds = data.word(kFreeframes);
+ bx = (0);
+ _add(bx, ax);
+ si = (0+2080);
+ al = ds.byte(bx);
+ ah = 0;
+ cl = ds.byte(bx+1);
+ ch = 0;
+ _add(si, ds.word(bx+2));
+ dx = ds.word(bx+4);
+ bx = pop();
+ es.byte(bx+0) = al;
+ es.byte(bx+1) = cl;
+ es.word(bx+4) = dx;
+ _mul(cx);
+ cx = ax;
+ push(cx);
+ _movsb(cx, true);
+ cx = pop();
+ ax = pop();
+ es.word(bx+2) = ax;
+ _add(data.word(kExframepos), cx);
+}
+
+void DreamGenContext::transfermap() {
+ STACK_CHECK;
+ di = data.word(kExframepos);
+ push(di);
+ al = data.byte(kExpos);
+ ah = 0;
+ bx = ax;
+ _add(ax, ax);
+ _add(ax, bx);
+ cx = 6;
+ _mul(cx);
+ es = data.word(kExtras);
+ bx = (0);
+ _add(bx, ax);
+ _add(di, (0+2080));
+ push(bx);
+ al = data.byte(kItemtotran);
+ ah = 0;
+ bx = ax;
+ _add(ax, ax);
+ _add(ax, bx);
+ cx = 6;
+ _mul(cx);
+ ds = data.word(kFreeframes);
+ bx = (0);
+ _add(bx, ax);
+ si = (0+2080);
+ al = ds.byte(bx);
+ ah = 0;
+ cl = ds.byte(bx+1);
+ ch = 0;
+ _add(si, ds.word(bx+2));
+ dx = ds.word(bx+4);
+ bx = pop();
+ es.byte(bx+0) = al;
+ es.byte(bx+1) = cl;
+ es.word(bx+4) = dx;
+ _mul(cx);
+ cx = ax;
+ push(cx);
+ _movsb(cx, true);
+ cx = pop();
+ ax = pop();
+ es.word(bx+2) = ax;
+ _add(data.word(kExframepos), cx);
+}
+
+void DreamGenContext::dofade() {
+ STACK_CHECK;
+ _cmp(data.byte(kFadedirection), 0);
+ if (flags.z())
+ return /* (finishfade) */;
+ cl = data.byte(kNumtofade);
+ ch = 0;
+ al = data.byte(kColourpos);
+ ah = 0;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ _add(si, ax);
+ _add(si, ax);
+ _add(si, ax);
+ showgroup();
+ al = data.byte(kNumtofade);
+ _add(al, data.byte(kColourpos));
+ data.byte(kColourpos) = al;
+ _cmp(al, 0);
+ if (!flags.z())
+ return /* (finishfade) */;
+ fadecalculation();
+}
+
+void DreamGenContext::clearendpal() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ cx = 768;
+ al = 0;
+ _stosb(cx, true);
+}
+
+void DreamGenContext::clearpalette() {
+ STACK_CHECK;
+ data.byte(kFadedirection) = 0;
+ clearstartpal();
+ dumpcurrent();
+}
+
+void DreamGenContext::fadescreenup() {
+ STACK_CHECK;
+ clearstartpal();
+ paltoendpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+}
+
+void DreamGenContext::fadetowhite() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ cx = 768;
+ al = 63;
+ _stosb(cx, true);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ al = 0;
+ _stosb(3);
+ paltostartpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+}
+
+void DreamGenContext::fadefromwhite() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ cx = 768;
+ al = 63;
+ _stosb(cx, true);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ al = 0;
+ _stosb(3);
+ paltoendpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+}
+
+void DreamGenContext::fadescreenups() {
+ STACK_CHECK;
+ clearstartpal();
+ paltoendpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 64;
+}
+
+void DreamGenContext::fadescreendownhalf() {
+ STACK_CHECK;
+ paltostartpal();
+ paltoendpal();
+ cx = 768;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+halfend:
+ al = es.byte(bx);
+ _shr(al, 1);
+ es.byte(bx) = al;
+ _inc(bx);
+ if (--cx)
+ goto halfend;
+ ds = data.word(kBuffers);
+ es = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3))+(56*3);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(56*3);
+ cx = 3*5;
+ _movsb(cx, true);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3))+(77*3);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(77*3);
+ cx = 3*2;
+ _movsb(cx, true);
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 31;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 32;
+}
+
+void DreamGenContext::fadescreenuphalf() {
+ STACK_CHECK;
+ endpaltostart();
+ paltoendpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 31;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 32;
+}
+
+void DreamGenContext::fadescreendown() {
+ STACK_CHECK;
+ paltostartpal();
+ clearendpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+}
+
+void DreamGenContext::fadescreendowns() {
+ STACK_CHECK;
+ paltostartpal();
+ clearendpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 64;
+}
+
+void DreamGenContext::clearstartpal() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ cx = 256;
+wholeloop1:
+ ax = 0;
+ _stosw();
+ al = 0;
+ _stosb();
+ if (--cx)
+ goto wholeloop1;
+}
+
+void DreamGenContext::showgun() {
+ STACK_CHECK;
+ data.byte(kAddtored) = 0;
+ data.byte(kAddtogreen) = 0;
+ data.byte(kAddtoblue) = 0;
+ paltostartpal();
+ paltoendpal();
+ greyscalesum();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+ cx = 130;
+ hangon();
+ endpaltostart();
+ clearendpal();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+ cx = 200;
+ hangon();
+ data.byte(kRoomssample) = 34;
+ loadroomssample();
+ data.byte(kVolume) = 0;
+ dx = 2351;
+ loadintotemp();
+ createpanel2();
+ ds = data.word(kTempgraphics);
+ al = 0;
+ ah = 0;
+ di = 100;
+ bx = 4;
+ showframe();
+ ds = data.word(kTempgraphics);
+ al = 1;
+ ah = 0;
+ di = 158;
+ bx = 106;
+ showframe();
+ worktoscreen();
+ getridoftemp();
+ fadescreenup();
+ cx = 160;
+ hangon();
+ al = 12;
+ ah = 0;
+ playchannel0();
+ dx = 2260;
+ loadtemptext();
+ rollendcredits2();
+ getridoftemptext();
+}
+
+void DreamGenContext::rollendcredits2() {
+ STACK_CHECK;
+ rollem();
+}
+
+void DreamGenContext::rollem() {
+ STACK_CHECK;
+ cl = 160;
+ ch = 160;
+ di = 25;
+ bx = 20;
+ ds = data.word(kMapstore);
+ si = 0;
+ multiget();
+ es = data.word(kTextfile1);
+ si = 49*2;
+ ax = es.word(si);
+ si = ax;
+ _add(si, (66*2));
+ cx = 80;
+endcredits21:
+ push(cx);
+ bx = 10;
+ cx = data.word(kLinespacing);
+endcredits22:
+ push(cx);
+ push(si);
+ push(di);
+ push(es);
+ push(bx);
+ vsync();
+ cl = 160;
+ ch = 160;
+ di = 25;
+ bx = 20;
+ ds = data.word(kMapstore);
+ si = 0;
+ multiput();
+ vsync();
+ bx = pop();
+ es = pop();
+ di = pop();
+ si = pop();
+ push(si);
+ push(di);
+ push(es);
+ push(bx);
+ cx = 18;
+onelot2:
+ push(cx);
+ di = 25;
+ dx = 161;
+ ax = 0;
+ printdirect();
+ _add(bx, data.word(kLinespacing));
+ cx = pop();
+ if (--cx)
+ goto onelot2;
+ vsync();
+ cl = 160;
+ ch = 160;
+ di = 25;
+ bx = 20;
+ multidump();
+ bx = pop();
+ es = pop();
+ di = pop();
+ si = pop();
+ cx = pop();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto endearly2;
+ _dec(bx);
+ if (--cx)
+ goto endcredits22;
+ cx = pop();
+looknext2:
+ al = es.byte(si);
+ _inc(si);
+ _cmp(al, ':');
+ if (flags.z())
+ goto gotnext2;
+ _cmp(al, 0);
+ if (flags.z())
+ goto gotnext2;
+ goto looknext2;
+gotnext2:
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ return /* (endearly) */;
+ if (--cx)
+ goto endcredits21;
+ cx = 120;
+ hangone();
+ return;
+endearly2:
+ cx = pop();
+}
+
+void DreamGenContext::fadecalculation() {
+ STACK_CHECK;
+ _cmp(data.byte(kFadecount), 0);
+ if (flags.z())
+ goto nomorefading;
+ bl = data.byte(kFadecount);
+ es = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ cx = 768;
+fadecolloop:
+ al = es.byte(si);
+ ah = es.byte(di);
+ _cmp(al, ah);
+ if (flags.z())
+ goto gotthere;
+ if (flags.c())
+ goto lesscolour;
+ _dec(es.byte(si));
+ goto gotthere;
+lesscolour:
+ _cmp(bl, ah);
+ if (flags.z())
+ goto withit;
+ if (!flags.c())
+ goto gotthere;
+withit:
+ _inc(es.byte(si));
+gotthere:
+ _inc(si);
+ _inc(di);
+ if (--cx)
+ goto fadecolloop;
+ _dec(data.byte(kFadecount));
+ return;
+nomorefading:
+ data.byte(kFadedirection) = 0;
+}
+
+void DreamGenContext::greyscalesum() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ cx = 256;
+greysumloop1:
+ push(cx);
+ bx = 0;
+ al = es.byte(si);
+ ah = 0;
+ cx = 20;
+ _mul(cx);
+ _add(bx, ax);
+ al = es.byte(si+1);
+ ah = 0;
+ cx = 59;
+ _mul(cx);
+ _add(bx, ax);
+ al = es.byte(si+2);
+ ah = 0;
+ cx = 11;
+ _mul(cx);
+ _add(bx, ax);
+ al = -1;
+greysumloop2:
+ _inc(al);
+ _sub(bx, 100);
+ if (!flags.c())
+ goto greysumloop2;
+ bl = al;
+ al = bl;
+ ah = data.byte(kAddtored);
+ _cmp(al, 0);
+ _add(al, ah);
+ _stosb();
+ ah = data.byte(kAddtogreen);
+ al = bl;
+ _cmp(al, 0);
+ if (flags.z())
+ goto noaddg;
+ _add(al, ah);
+noaddg:
+ _stosb();
+ ah = data.byte(kAddtoblue);
+ al = bl;
+ _cmp(al, 0);
+ if (flags.z())
+ goto noaddb;
+ _add(al, ah);
+noaddb:
+ _stosb();
+ _add(si, 3);
+ cx = pop();
+ if (--cx)
+ goto greysumloop1;
+}
+
+void DreamGenContext::paltostartpal() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ cx = 768/2;
+ _movsw(cx, true);
+}
+
+void DreamGenContext::endpaltostart() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ cx = 768/2;
+ _movsw(cx, true);
+}
+
+void DreamGenContext::startpaltoend() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ ds = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ cx = 768/2;
+ _movsw(cx, true);
+}
+
+void DreamGenContext::paltoendpal() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ ds = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768);
+ cx = 768/2;
+ _movsw(cx, true);
+}
+
+void DreamGenContext::allpalette() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ ds = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768);
+ cx = 768/2;
+ _movsw(cx, true);
+ dumpcurrent();
+}
+
+void DreamGenContext::dumpcurrent() {
+ STACK_CHECK;
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ ds = data.word(kBuffers);
+ vsync();
+ al = 0;
+ cx = 128;
+ showgroup();
+ vsync();
+ al = 128;
+ cx = 128;
+ showgroup();
+}
+
+void DreamGenContext::fadedownmon() {
+ STACK_CHECK;
+ paltostartpal();
+ paltoendpal();
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(231*3);
+ cx = 3*8;
+ ax = 0;
+ _stosb(cx, true);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(246*3);
+ _stosb();
+ _stosw();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+ cx = 64;
+ hangon();
+}
+
+void DreamGenContext::fadeupmon() {
+ STACK_CHECK;
+ paltostartpal();
+ paltoendpal();
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3))+(231*3);
+ cx = 3*8;
+ ax = 0;
+ _stosb(cx, true);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3))+(246*3);
+ _stosb();
+ _stosw();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+ cx = 128;
+ hangon();
+}
+
+void DreamGenContext::fadeupmonfirst() {
+ STACK_CHECK;
+ paltostartpal();
+ paltoendpal();
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3))+(231*3);
+ cx = 3*8;
+ ax = 0;
+ _stosb(cx, true);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3))+(246*3);
+ _stosb();
+ _stosw();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+ cx = 64;
+ hangon();
+ al = 26;
+ playchannel1();
+ cx = 64;
+ hangon();
+}
+
+void DreamGenContext::fadeupyellows() {
+ STACK_CHECK;
+ paltoendpal();
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(231*3);
+ cx = 3*8;
+ ax = 0;
+ _stosb(cx, true);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(246*3);
+ _stosb();
+ _stosw();
+ data.byte(kFadedirection) = 1;
+ data.byte(kFadecount) = 63;
+ data.byte(kColourpos) = 0;
+ data.byte(kNumtofade) = 128;
+ cx = 128;
+ hangon();
+}
+
+void DreamGenContext::initialmoncols() {
+ STACK_CHECK;
+ paltostartpal();
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3))+(230*3);
+ cx = 3*9;
+ ax = 0;
+ _stosb(cx, true);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3))+(246*3);
+ _stosb();
+ _stosw();
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3))+(230*3);
+ al = 230;
+ cx = 18;
+ showgroup();
+}
+
+void DreamGenContext::titles() {
+ STACK_CHECK;
+ clearpalette();
+ biblequote();
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (titlesearly) */;
+ intro();
+}
+
+void DreamGenContext::endgame() {
+ STACK_CHECK;
+ dx = 2260;
+ loadtemptext();
+ monkspeaking();
+ gettingshot();
+ getridoftemptext();
+ data.byte(kVolumeto) = 7;
+ data.byte(kVolumedirection) = 1;
+ cx = 200;
+ hangon();
+}
+
+void DreamGenContext::monkspeaking() {
+ STACK_CHECK;
+ data.byte(kRoomssample) = 35;
+ loadroomssample();
+ dx = 2364;
+ loadintotemp();
+ clearwork();
+ showmonk();
+ worktoscreen();
+ data.byte(kVolume) = 7;
+ data.byte(kVolumedirection) = -1;
+ data.byte(kVolumeto) = 5;
+ al = 12;
+ ah = 255;
+ playchannel0();
+ fadescreenups();
+ cx = 300;
+ hangon();
+ al = 40;
+loadspeech2:
+ push(ax);
+ dl = 'T';
+ dh = 83;
+ cl = 'T';
+ ah = 0;
+ loadspeech();
+ al = 50+12;
+ playchannel1();
+notloadspeech2:
+ vsync();
+ _cmp(data.byte(kCh1playing), 255);
+ if (!flags.z())
+ goto notloadspeech2;
+ ax = pop();
+ _inc(al);
+ _cmp(al, 48);
+ if (!flags.z())
+ goto loadspeech2;
+ data.byte(kVolumedirection) = 1;
+ data.byte(kVolumeto) = 7;
+ fadescreendowns();
+ cx = 300;
+ hangon();
+ getridoftemp();
+}
+
+void DreamGenContext::showmonk() {
+ STACK_CHECK;
+ al = 0;
+ ah = 128;
+ di = 160;
+ bx = 72;
+ ds = data.word(kTempgraphics);
+ showframe();
+}
+
+void DreamGenContext::gettingshot() {
+ STACK_CHECK;
+ data.byte(kNewlocation) = 55;
+ clearpalette();
+ loadintroroom();
+ fadescreenups();
+ data.byte(kVolumeto) = 0;
+ data.byte(kVolumedirection) = -1;
+ runendseq();
+ clearbeforeload();
+}
+
+void DreamGenContext::credits() {
+ STACK_CHECK;
+ clearpalette();
+ realcredits();
+}
+
+void DreamGenContext::biblequote() {
+ STACK_CHECK;
+ mode640x480();
+ dx = 2377;
+ showpcx();
+ fadescreenups();
+ cx = 80;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto biblequotearly;
+ cx = 560;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto biblequotearly;
+ fadescreendowns();
+ cx = 200;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto biblequotearly;
+ cancelch0();
+biblequotearly:
+ data.byte(kLasthardkey) = 0;
+}
+
+void DreamGenContext::hangone() {
+ STACK_CHECK;
+hangonloope:
+ push(cx);
+ vsync();
+ cx = pop();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ return /* (hangonearly) */;
+ if (--cx)
+ goto hangonloope;
+}
+
+void DreamGenContext::intro() {
+ STACK_CHECK;
+ dx = 2247;
+ loadtemptext();
+ loadpalfromiff();
+ setmode();
+ data.byte(kNewlocation) = 50;
+ clearpalette();
+ loadintroroom();
+ data.byte(kVolume) = 7;
+ data.byte(kVolumedirection) = -1;
+ data.byte(kVolumeto) = 4;
+ al = 12;
+ ah = 255;
+ playchannel0();
+ fadescreenups();
+ runintroseq();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto introearly;
+ clearbeforeload();
+ data.byte(kNewlocation) = 52;
+ loadintroroom();
+ runintroseq();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto introearly;
+ clearbeforeload();
+ data.byte(kNewlocation) = 53;
+ loadintroroom();
+ runintroseq();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto introearly;
+ clearbeforeload();
+ allpalette();
+ data.byte(kNewlocation) = 54;
+ loadintroroom();
+ runintroseq();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto introearly;
+ getridoftemptext();
+ clearbeforeload();
+introearly:
+ data.byte(kLasthardkey) = 0;
+}
+
+void DreamGenContext::runintroseq() {
+ STACK_CHECK;
+ data.byte(kGetback) = 0;
+moreintroseq:
+ vsync();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto earlyendrun;
+ spriteupdate();
+ vsync();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto earlyendrun;
+ deleverything();
+ printsprites();
+ reelsonscreen();
+ afterintroroom();
+ usetimedtext();
+ vsync();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto earlyendrun;
+ dumpmap();
+ dumptimedtext();
+ vsync();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto earlyendrun;
+ _cmp(data.byte(kGetback), 1);
+ if (!flags.z())
+ goto moreintroseq;
+ return;
+earlyendrun:
+ getridoftemptext();
+ clearbeforeload();
+}
+
+void DreamGenContext::runendseq() {
+ STACK_CHECK;
+ atmospheres();
+ data.byte(kGetback) = 0;
+moreendseq:
+ vsync();
+ spriteupdate();
+ vsync();
+ deleverything();
+ printsprites();
+ reelsonscreen();
+ afterintroroom();
+ usetimedtext();
+ vsync();
+ dumpmap();
+ dumptimedtext();
+ vsync();
+ _cmp(data.byte(kGetback), 1);
+ if (!flags.z())
+ goto moreendseq;
+}
+
+void DreamGenContext::loadintroroom() {
+ STACK_CHECK;
+ data.byte(kIntrocount) = 0;
+ data.byte(kLocation) = 255;
+ loadroom();
+ data.word(kMapoffsetx) = 72;
+ data.word(kMapoffsety) = 16;
+ clearsprites();
+ data.byte(kThroughdoor) = 0;
+ data.byte(kCurrentkey) = '0';
+ data.byte(kMainmode) = 0;
+ clearwork();
+ data.byte(kNewobs) = 1;
+ drawfloor();
+ reelsonscreen();
+ spriteupdate();
+ printsprites();
+ worktoscreen();
+}
+
+void DreamGenContext::realcredits() {
+ STACK_CHECK;
+ data.byte(kRoomssample) = 33;
+ loadroomssample();
+ data.byte(kVolume) = 0;
+ mode640x480();
+ cx = 35;
+ hangon();
+ dx = 2390;
+ showpcx();
+ al = 12;
+ ah = 0;
+ playchannel0();
+ cx = 2;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ allpalette();
+ cx = 80;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ fadescreendowns();
+ cx = 256;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ dx = 2403;
+ showpcx();
+ al = 12;
+ ah = 0;
+ playchannel0();
+ cx = 2;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ allpalette();
+ cx = 80;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ fadescreendowns();
+ cx = 256;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ dx = 2416;
+ showpcx();
+ al = 12;
+ ah = 0;
+ playchannel0();
+ cx = 2;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ allpalette();
+ cx = 80;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ fadescreendowns();
+ cx = 256;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ dx = 2429;
+ showpcx();
+ al = 12;
+ ah = 0;
+ playchannel0();
+ cx = 2;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ allpalette();
+ cx = 80;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ fadescreendowns();
+ cx = 256;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ dx = 2442;
+ showpcx();
+ al = 12;
+ ah = 0;
+ playchannel0();
+ cx = 2;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ allpalette();
+ cx = 80;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ fadescreendowns();
+ cx = 256;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ dx = 2455;
+ showpcx();
+ fadescreenups();
+ cx = 60;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ al = 13;
+ ah = 0;
+ playchannel0();
+ cx = 350;
+ hangone();
+ _cmp(data.byte(kLasthardkey), 1);
+ if (flags.z())
+ goto realcreditsearly;
+ fadescreendowns();
+ cx = 256;
+ hangone();
+realcreditsearly:
+ data.byte(kLasthardkey) = 0;
+}
+
+void DreamGenContext::printchar() {
+ STACK_CHECK;
+ _cmp(al, 255);
+ if (flags.z())
+ return /* (ignoreit) */;
+ push(si);
+ push(bx);
+ push(di);
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(bx, 3);
+_tmp1:
+ push(ax);
+ _sub(al, 32);
+ ah = 0;
+ _add(ax, data.word(kCharshift));
+ showframe();
+ ax = pop();
+ di = pop();
+ bx = pop();
+ si = pop();
+ _cmp(data.byte(kKerning), 0);
+ if (!flags.z())
+ goto nokern;
+ kernchars();
+nokern:
+ push(cx);
+ ch = 0;
+ _add(di, cx);
+ cx = pop();
+}
+
+void DreamGenContext::kernchars() {
+ STACK_CHECK;
+ _cmp(al, 'a');
+ if (flags.z())
+ goto iskern;
+ _cmp(al, 'u');
+ if (flags.z())
+ goto iskern;
+ return;
+iskern:
+ _cmp(ah, 'n');
+ if (flags.z())
+ goto kernit;
+ _cmp(ah, 't');
+ if (flags.z())
+ goto kernit;
+ _cmp(ah, 'r');
+ if (flags.z())
+ goto kernit;
+ _cmp(ah, 'i');
+ if (flags.z())
+ goto kernit;
+ _cmp(ah, 'l');
+ if (flags.z())
+ goto kernit;
+ return;
+kernit:
+ _dec(cl);
+}
+
+void DreamGenContext::printslow() {
+ STACK_CHECK;
+ data.byte(kPointerframe) = 1;
+ data.byte(kPointermode) = 3;
+ ds = data.word(kCharset1);
+printloopslow6:
+ push(bx);
+ push(di);
+ push(dx);
+ getnumber();
+ ch = 0;
+printloopslow5:
+ push(cx);
+ push(si);
+ push(es);
+ ax = es.word(si);
+ push(bx);
+ push(cx);
+ push(es);
+ push(si);
+ push(ds);
+ modifychar();
+ printboth();
+ ds = pop();
+ si = pop();
+ es = pop();
+ cx = pop();
+ bx = pop();
+ ax = es.word(si+1);
+ _inc(si);
+ _cmp(al, 0);
+ if (flags.z())
+ goto finishslow;
+ _cmp(al, ':');
+ if (flags.z())
+ goto finishslow;
+ _cmp(cl, 1);
+ if (flags.z())
+ goto afterslow;
+ push(di);
+ push(ds);
+ push(bx);
+ push(cx);
+ push(es);
+ push(si);
+ modifychar();
+ data.word(kCharshift) = 91;
+ printboth();
+ data.word(kCharshift) = 0;
+ si = pop();
+ es = pop();
+ cx = pop();
+ bx = pop();
+ ds = pop();
+ di = pop();
+ waitframes();
+ _cmp(ax, 0);
+ if (flags.z())
+ goto keepgoing;
+ _cmp(ax, data.word(kOldbutton));
+ if (!flags.z())
+ goto finishslow2;
+keepgoing:
+ waitframes();
+ _cmp(ax, 0);
+ if (flags.z())
+ goto afterslow;
+ _cmp(ax, data.word(kOldbutton));
+ if (!flags.z())
+ goto finishslow2;
+afterslow:
+ es = pop();
+ si = pop();
+ cx = pop();
+ _inc(si);
+ if (--cx)
+ goto printloopslow5;
+ dx = pop();
+ di = pop();
+ bx = pop();
+ _add(bx, 10);
+ goto printloopslow6;
+finishslow:
+ es = pop();
+ si = pop();
+ cx = pop();
+ dx = pop();
+ di = pop();
+ bx = pop();
+ al = 0;
+ return;
+finishslow2:
+ es = pop();
+ si = pop();
+ cx = pop();
+ dx = pop();
+ di = pop();
+ bx = pop();
+ al = 1;
+}
+
+void DreamGenContext::waitframes() {
+ STACK_CHECK;
+ push(di);
+ push(bx);
+ push(es);
+ push(si);
+ push(ds);
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ delpointer();
+ ax = data.word(kMousebutton);
+ ds = pop();
+ si = pop();
+ es = pop();
+ bx = pop();
+ di = pop();
+}
+
+void DreamGenContext::printboth() {
+ STACK_CHECK;
+ push(ax);
+ push(cx);
+ push(bx);
+ push(di);
+ printchar();
+ ax = pop();
+ push(di);
+ di = ax;
+ multidump();
+ di = pop();
+ bx = pop();
+ cx = pop();
+ ax = pop();
+}
+
+void DreamGenContext::printdirect() {
+ STACK_CHECK;
+ data.word(kLastxpos) = di;
+ ds = data.word(kCurrentset);
+printloop6:
+ push(bx);
+ push(di);
+ push(dx);
+ getnumber();
+ ch = 0;
+printloop5:
+ ax = es.word(si);
+ _inc(si);
+ _cmp(al, 0);
+ if (flags.z())
+ goto finishdirct;
+ _cmp(al, ':');
+ if (flags.z())
+ goto finishdirct;
+ push(cx);
+ push(es);
+ modifychar();
+ printchar();
+ data.word(kLastxpos) = di;
+ es = pop();
+ cx = pop();
+ if (--cx)
+ goto printloop5;
+ dx = pop();
+ di = pop();
+ bx = pop();
+ _add(bx, data.word(kLinespacing));
+ goto printloop6;
+finishdirct:
+ dx = pop();
+ di = pop();
+ bx = pop();
+}
+
+void DreamGenContext::monprint() {
+ STACK_CHECK;
+ data.byte(kKerning) = 1;
+ si = bx;
+ dl = 166;
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ ds = data.word(kTempcharset);
+printloop8:
+ push(bx);
+ push(di);
+ push(dx);
+ getnumber();
+ ch = 0;
+printloop7:
+ al = es.byte(si);
+ _inc(si);
+ _cmp(al, ':');
+ if (flags.z())
+ goto finishmon2;
+ _cmp(al, 0);
+ if (flags.z())
+ goto finishmon;
+ _cmp(al, 34);
+ if (flags.z())
+ goto finishmon;
+ _cmp(al, '=');
+ if (flags.z())
+ goto finishmon;
+ _cmp(al, '%');
+ if (!flags.z())
+ goto nottrigger;
+ ah = es.byte(si);
+ _inc(si);
+ _inc(si);
+ goto finishmon;
+nottrigger:
+ push(cx);
+ push(es);
+ modifychar();
+ printchar();
+ data.word(kCurslocx) = di;
+ data.word(kCurslocy) = bx;
+ data.word(kMaintimer) = 1;
+ printcurs();
+ vsync();
+ push(si);
+ push(dx);
+ push(ds);
+ push(es);
+ push(bx);
+ push(di);
+ lockmon();
+ di = pop();
+ bx = pop();
+ es = pop();
+ ds = pop();
+ dx = pop();
+ si = pop();
+ delcurs();
+ es = pop();
+ cx = pop();
+ if (--cx)
+ goto printloop7;
+finishmon2:
+ dx = pop();
+ di = pop();
+ bx = pop();
+ scrollmonitor();
+ data.word(kCurslocx) = di;
+ goto printloop8;
+finishmon:
+ dx = pop();
+ di = pop();
+ bx = pop();
+ _cmp(al, '%');
+ if (!flags.z())
+ goto nottrigger2;
+ data.byte(kLasttrigger) = ah;
+nottrigger2:
+ data.word(kCurslocx) = di;
+ scrollmonitor();
+ bx = si;
+ data.byte(kKerning) = 0;
+}
+
+void DreamGenContext::getnumber() {
+ STACK_CHECK;
+ cx = 0;
+ push(si);
+ push(bx);
+ push(di);
+ push(ds);
+ push(es);
+ di = si;
+wordloop:
+ push(cx);
+ push(dx);
+ getnextword();
+ dx = pop();
+ cx = pop();
+ _cmp(al, 1);
+ if (flags.z())
+ goto endoftext;
+ al = cl;
+ ah = 0;
+ push(bx);
+ bh = 0;
+ _add(ax, bx);
+ bx = pop();
+ _sub(ax, 10);
+ dh = 0;
+ _cmp(ax, dx);
+ if (!flags.c())
+ goto gotoverend;
+ _add(cl, bl);
+ _add(ch, bh);
+ goto wordloop;
+gotoverend:
+ al = dl;
+ _and(al, 1);
+ if (flags.z())
+ goto notcentre;
+ push(cx);
+ al = dl;
+ _and(al, 0xfe);
+ ah = 0;
+ ch = 0;
+ _sub(ax, cx);
+ _add(ax, 20);
+ _shr(ax, 1);
+ cx = pop();
+ es = pop();
+ ds = pop();
+ di = pop();
+ bx = pop();
+ si = pop();
+ _add(di, ax);
+ cl = ch;
+ return;
+notcentre:
+ es = pop();
+ ds = pop();
+ di = pop();
+ bx = pop();
+ si = pop();
+ cl = ch;
+ return;
+endoftext:
+ al = cl;
+ ah = 0;
+ push(bx);
+ bh = 0;
+ _add(ax, bx);
+ bx = pop();
+ _sub(ax, 10);
+ dh = 0;
+ _cmp(ax, dx);
+ if (!flags.c())
+ goto gotoverend2;
+ _add(cl, bl);
+ _add(ch, bh);
+gotoverend2:
+ al = dl;
+ _and(al, 1);
+ if (flags.z())
+ goto notcent2;
+ push(cx);
+ al = dl;
+ _and(al, 0xfe);
+ _add(al, 2);
+ ah = 0;
+ ch = 0;
+ _add(ax, 20);
+ _sub(ax, cx);
+ _shr(ax, 1);
+ cx = pop();
+ es = pop();
+ ds = pop();
+ di = pop();
+ bx = pop();
+ si = pop();
+ _add(di, ax);
+ cl = ch;
+ return;
+notcent2:
+ es = pop();
+ ds = pop();
+ di = pop();
+ bx = pop();
+ si = pop();
+ cl = ch;
+}
+
+void DreamGenContext::getnextword() {
+ STACK_CHECK;
+ bx = 0;
+getloop:
+ ax = es.word(di);
+ _inc(di);
+ _inc(bh);
+ _cmp(al, ':');
+ if (flags.z())
+ goto endall;
+ _cmp(al, 0);
+ if (flags.z())
+ goto endall;
+ _cmp(al, 32);
+ if (flags.z())
+ goto endword;
+ modifychar();
+ _cmp(al, 255);
+ if (flags.z())
+ goto getloop;
+ push(ax);
+ _sub(al, 32);
+ ah = 0;
+ _add(ax, data.word(kCharshift));
+ _add(ax, ax);
+ si = ax;
+ _add(ax, ax);
+ _add(si, ax);
+ cl = ds.byte(si+0);
+ ax = pop();
+ kernchars();
+ _add(bl, cl);
+ goto getloop;
+endword:
+ _add(bl, 6);
+ al = 0;
+ return;
+endall:
+ _add(bl, 6);
+ al = 1;
+}
+
+void DreamGenContext::fillryan() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32);
+ findallryan();
+ si = (0+(228*13)+32);
+ al = data.byte(kRyanpage);
+ ah = 0;
+ cx = 20;
+ _mul(cx);
+ _add(si, ax);
+ di = (80);
+ bx = (58);
+ cx = 2;
+ryanloop2:
+ push(cx);
+ push(di);
+ push(bx);
+ cx = 5;
+ryanloop1:
+ push(cx);
+ push(di);
+ push(bx);
+ ax = es.word(si);
+ _add(si, 2);
+ push(si);
+ push(es);
+ obtoinv();
+ es = pop();
+ si = pop();
+ bx = pop();
+ di = pop();
+ cx = pop();
+ _add(di, (44));
+ if (--cx)
+ goto ryanloop1;
+ bx = pop();
+ di = pop();
+ cx = pop();
+ _add(bx, (44));
+ if (--cx)
+ goto ryanloop2;
+ showryanpage();
+}
+
+void DreamGenContext::fillopen() {
+ STACK_CHECK;
+ deltextline();
+ getopenedsize();
+ _cmp(ah, 4);
+ if (flags.c())
+ goto lessthanapage;
+ ah = 4;
+lessthanapage:
+ al = 1;
+ push(ax);
+ es = data.word(kBuffers);
+ di = (0+(228*13));
+ findallopen();
+ si = (0+(228*13));
+ di = (80);
+ bx = (58)+96;
+ cx = pop();
+openloop1:
+ push(cx);
+ push(di);
+ push(bx);
+ ax = es.word(si);
+ _add(si, 2);
+ push(si);
+ push(es);
+ _cmp(ch, cl);
+ if (flags.c())
+ goto nextopenslot;
+ obtoinv();
+nextopenslot:
+ es = pop();
+ si = pop();
+ bx = pop();
+ di = pop();
+ cx = pop();
+ _add(di, (44));
+ _inc(cl);
+ _cmp(cl, 5);
+ if (!flags.z())
+ goto openloop1;
+ undertextline();
+}
+
+void DreamGenContext::findallryan() {
+ STACK_CHECK;
+ push(di);
+ cx = 30;
+ ax = 0x0ffff;
+ _stosw(cx, true);
+ di = pop();
+ cl = 4;
+ ds = data.word(kExtras);
+ bx = (0+2080+30000);
+ ch = 0;
+findryanloop:
+ _cmp(ds.byte(bx+2), cl);
+ if (!flags.z())
+ goto notinryaninv;
+ _cmp(ds.byte(bx+3), 255);
+ if (!flags.z())
+ goto notinryaninv;
+ al = ds.byte(bx+4);
+ ah = 0;
+ push(di);
+ _add(di, ax);
+ _add(di, ax);
+ al = ch;
+ ah = 4;
+ _stosw();
+ di = pop();
+notinryaninv:
+ _add(bx, 16);
+ _inc(ch);
+ _cmp(ch, (114));
+ if (!flags.z())
+ goto findryanloop;
+}
+
+void DreamGenContext::findallopen() {
+ STACK_CHECK;
+ push(di);
+ cx = 16;
+ ax = 0x0ffff;
+ _stosw(cx, true);
+ di = pop();
+ cl = data.byte(kOpenedob);
+ dl = data.byte(kOpenedtype);
+ ds = data.word(kExtras);
+ bx = (0+2080+30000);
+ ch = 0;
+findopen1:
+ _cmp(ds.byte(bx+3), cl);
+ if (!flags.z())
+ goto findopen2;
+ _cmp(ds.byte(bx+2), dl);
+ if (!flags.z())
+ goto findopen2;
+ _cmp(data.byte(kOpenedtype), 4);
+ if (flags.z())
+ goto noloccheck;
+ al = ds.byte(bx+5);
+ _cmp(al, data.byte(kReallocation));
+ if (!flags.z())
+ goto findopen2;
+noloccheck:
+ al = ds.byte(bx+4);
+ ah = 0;
+ push(di);
+ _add(di, ax);
+ _add(di, ax);
+ al = ch;
+ ah = 4;
+ _stosw();
+ di = pop();
+findopen2:
+ _add(bx, 16);
+ _inc(ch);
+ _cmp(ch, (114));
+ if (!flags.z())
+ goto findopen1;
+ cl = data.byte(kOpenedob);
+ dl = data.byte(kOpenedtype);
+ push(dx);
+ ds = data.word(kFreedat);
+ dx = pop();
+ bx = 0;
+ ch = 0;
+findopen1a:
+ _cmp(ds.byte(bx+3), cl);
+ if (!flags.z())
+ goto findopen2a;
+ _cmp(ds.byte(bx+2), dl);
+ if (!flags.z())
+ goto findopen2a;
+ al = ds.byte(bx+4);
+ ah = 0;
+ push(di);
+ _add(di, ax);
+ _add(di, ax);
+ al = ch;
+ ah = 2;
+ _stosw();
+ di = pop();
+findopen2a:
+ _add(bx, 16);
+ _inc(ch);
+ _cmp(ch, 80);
+ if (!flags.z())
+ goto findopen1a;
+}
+
+void DreamGenContext::obtoinv() {
+ STACK_CHECK;
+ push(bx);
+ push(es);
+ push(si);
+ push(ax);
+ push(ax);
+ push(di);
+ push(bx);
+ ds = data.word(kIcons1);
+ _sub(di, 2);
+ _sub(bx, 1);
+ al = 10;
+ ah = 0;
+ showframe();
+ bx = pop();
+ di = pop();
+ ax = pop();
+ _cmp(al, 255);
+ if (flags.z())
+ goto finishfill;
+ push(bx);
+ push(di);
+ push(ax);
+ ds = data.word(kExtras);
+ _cmp(ah, 4);
+ if (flags.z())
+ goto isanextra;
+ ds = data.word(kFreeframes);
+isanextra:
+ cl = al;
+ _add(al, al);
+ _add(al, cl);
+ _inc(al);
+ ah = 128;
+ _add(bx, 19);
+ _add(di, 18);
+ showframe();
+ ax = pop();
+ di = pop();
+ bx = pop();
+ push(bx);
+ getanyaddir();
+ isitworn();
+ bx = pop();
+ if (!flags.z())
+ goto finishfill;
+ ds = data.word(kIcons1);
+ _sub(di, 3);
+ _sub(bx, 2);
+ al = 7;
+ ah = 0;
+ showframe();
+finishfill:
+ ax = pop();
+ si = pop();
+ es = pop();
+ bx = pop();
+}
+
+void DreamGenContext::isitworn() {
+ STACK_CHECK;
+ al = es.byte(bx+12);
+ _cmp(al, 'W'-'A');
+ if (!flags.z())
+ return /* (notworn) */;
+ al = es.byte(bx+13);
+ _cmp(al, 'E'-'A');
+}
+
+void DreamGenContext::makeworn() {
+ STACK_CHECK;
+ es.byte(bx+12) = 'W'-'A';
+ es.byte(bx+13) = 'E'-'A';
+}
+
+void DreamGenContext::examineob() {
+ STACK_CHECK;
+ data.byte(kPointermode) = 0;
+ data.word(kTimecount) = 0;
+examineagain:
+ data.byte(kInmaparea) = 0;
+ data.byte(kExamagain) = 0;
+ data.byte(kOpenedob) = 255;
+ data.byte(kOpenedtype) = 255;
+ data.byte(kInvopen) = 0;
+ al = data.byte(kCommandtype);
+ data.byte(kObjecttype) = al;
+ data.byte(kItemframe) = 0;
+ data.byte(kPointerframe) = 0;
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ obicons();
+ obpicture();
+ describeob();
+ undertextline();
+ data.byte(kCommandtype) = 255;
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+waitexam:
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ delpointer();
+ data.byte(kGetback) = 0;
+ bx = 2494;
+ _cmp(data.byte(kInvopen), 0);
+ if (flags.z())
+ goto notuseinv;
+ bx = 2556;
+ _cmp(data.byte(kInvopen), 1);
+ if (flags.z())
+ goto notuseinv;
+ bx = 2618;
+notuseinv:
+ checkcoords();
+ _cmp(data.byte(kExamagain), 0);
+ if (flags.z())
+ goto norex;
+ goto examineagain;
+norex:
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto waitexam;
+ data.byte(kPickup) = 0;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ goto iswatching;
+ _cmp(data.byte(kNewlocation), 255);
+ if (!flags.z())
+ goto justgetback;
+iswatching:
+ makemainscreen();
+ data.byte(kInvopen) = 0;
+ data.byte(kOpenedob) = 255;
+ return;
+justgetback:
+ data.byte(kInvopen) = 0;
+ data.byte(kOpenedob) = 255;
+}
+
+void DreamGenContext::makemainscreen() {
+ STACK_CHECK;
+ createpanel();
+ data.byte(kNewobs) = 1;
+ drawfloor();
+ spriteupdate();
+ printsprites();
+ reelsonscreen();
+ showicon();
+ getunderzoom();
+ undertextline();
+ data.byte(kCommandtype) = 255;
+ animpointer();
+ worktoscreenm();
+ data.byte(kCommandtype) = 200;
+ data.byte(kManisoffscreen) = 0;
+}
+
+void DreamGenContext::getbackfromob() {
+ STACK_CHECK;
+ _cmp(data.byte(kPickup), 1);
+ if (!flags.z())
+ goto notheldob;
+ blank();
+ return;
+notheldob:
+ getback1();
+}
+
+void DreamGenContext::incryanpage() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 222);
+ if (flags.z())
+ goto alreadyincryan;
+ data.byte(kCommandtype) = 222;
+ al = 31;
+ commandonly();
+alreadyincryan:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (noincryan) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doincryan;
+ return;
+doincryan:
+ ax = data.word(kMousex);
+ _sub(ax, (80)+167);
+ data.byte(kRyanpage) = -1;
+findnewpage:
+ _inc(data.byte(kRyanpage));
+ _sub(ax, 18);
+ if (!flags.c())
+ goto findnewpage;
+ delpointer();
+ fillryan();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::openinv() {
+ STACK_CHECK;
+ data.byte(kInvopen) = 1;
+ al = 61;
+ di = (80);
+ bx = (58)-10;
+ dl = 240;
+ printmessage();
+ fillryan();
+ data.byte(kCommandtype) = 255;
+}
+
+void DreamGenContext::showryanpage() {
+ STACK_CHECK;
+ ds = data.word(kIcons1);
+ di = (80)+167;
+ bx = (58)-12;
+ al = 12;
+ ah = 0;
+ showframe();
+ al = 13;
+ _add(al, data.byte(kRyanpage));
+ push(ax);
+ al = data.byte(kRyanpage);
+ ah = 0;
+ cx = 18;
+ _mul(cx);
+ ds = data.word(kIcons1);
+ di = (80)+167;
+ _add(di, ax);
+ bx = (58)-12;
+ ax = pop();
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::openob() {
+ STACK_CHECK;
+ al = data.byte(kOpenedob);
+ ah = data.byte(kOpenedtype);
+ di = 5847;
+ copyname();
+ di = (80);
+ bx = (58)+86;
+ al = 62;
+ dl = 240;
+ printmessage();
+ di = data.word(kLastxpos);
+ _add(di, 5);
+ bx = (58)+86;
+ es = cs;
+ si = 5847;
+ dl = 220;
+ al = 0;
+ ah = 0;
+ printdirect();
+ fillopen();
+ getopenedsize();
+ al = ah;
+ ah = 0;
+ cx = (44);
+ _mul(cx);
+ _add(ax, (80));
+ bx = 2588;
+ cs.word(bx) = ax;
+}
+
+void DreamGenContext::obicons() {
+ STACK_CHECK;
+ al = data.byte(kCommand);
+ getanyad();
+ _cmp(al, 255);
+ if (flags.z())
+ goto cantopenit;
+ ds = data.word(kIcons2);
+ di = 210;
+ bx = 1;
+ al = 4;
+ ah = 0;
+ showframe();
+cantopenit:
+ ds = data.word(kIcons2);
+ di = 260;
+ bx = 1;
+ al = 1;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::examicon() {
+ STACK_CHECK;
+ ds = data.word(kIcons2);
+ di = 254;
+ bx = 5;
+ al = 3;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::obpicture() {
+ STACK_CHECK;
+ al = data.byte(kCommand);
+ ah = data.byte(kObjecttype);
+ _cmp(ah, 1);
+ if (flags.z())
+ return /* (setframe) */;
+ _cmp(ah, 4);
+ if (flags.z())
+ goto exframe;
+ ds = data.word(kFreeframes);
+ di = 160;
+ bx = 68;
+ cl = al;
+ _add(al, al);
+ _add(al, cl);
+ _inc(al);
+ ah = 128;
+ showframe();
+ return;
+exframe:
+ ds = data.word(kExtras);
+ di = 160;
+ bx = 68;
+ cl = al;
+ _add(al, al);
+ _add(al, cl);
+ _inc(al);
+ ah = 128;
+ showframe();
+}
+
+void DreamGenContext::describeob() {
+ STACK_CHECK;
+ getobtextstart();
+ di = 33;
+ bx = 92;
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto notsetd;
+ _cmp(data.byte(kObjecttype), 1);
+ if (!flags.z())
+ goto notsetd;
+ bx = 82;
+notsetd:
+ dl = 241;
+ ah = 16;
+ data.word(kCharshift) = 91+91;
+ printdirect();
+ data.word(kCharshift) = 0;
+ di = 36;
+ bx = 104;
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto notsetd2;
+ _cmp(data.byte(kObjecttype), 1);
+ if (!flags.z())
+ goto notsetd2;
+ bx = 94;
+notsetd2:
+ dl = 241;
+ ah = 0;
+ printdirect();
+ push(bx);
+ obsthatdothings();
+ bx = pop();
+ additionaltext();
+}
+
+void DreamGenContext::additionaltext() {
+ STACK_CHECK;
+ _add(bx, 10);
+ push(bx);
+ al = data.byte(kCommand);
+ ah = data.byte(kObjecttype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto emptycup;
+ al = data.byte(kCommand);
+ ah = data.byte(kObjecttype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'F';
+ compare();
+ if (flags.z())
+ goto fullcup;
+ bx = pop();
+ return;
+emptycup:
+ al = 40;
+ findpuztext();
+ bx = pop();
+ di = 36;
+ dl = 241;
+ ah = 0;
+ printdirect();
+ return;
+fullcup:
+ al = 39;
+ findpuztext();
+ bx = pop();
+ di = 36;
+ dl = 241;
+ ah = 0;
+ printdirect();
+}
+
+void DreamGenContext::obsthatdothings() {
+ STACK_CHECK;
+ al = data.byte(kCommand);
+ ah = data.byte(kObjecttype);
+ cl = 'M';
+ ch = 'E';
+ dl = 'M';
+ dh = 'B';
+ compare();
+ if (!flags.z())
+ return /* (notlouiscard) */;
+ al = 4;
+ getlocation();
+ _cmp(al, 1);
+ if (flags.z())
+ return /* (seencard) */;
+ al = 4;
+ setlocation();
+ lookatcard();
+}
+
+void DreamGenContext::getobtextstart() {
+ STACK_CHECK;
+ es = data.word(kFreedesc);
+ si = (0);
+ cx = (0+(82*2));
+ _cmp(data.byte(kObjecttype), 2);
+ if (flags.z())
+ goto describe;
+ es = data.word(kSetdesc);
+ si = (0);
+ cx = (0+(130*2));
+ _cmp(data.byte(kObjecttype), 1);
+ if (flags.z())
+ goto describe;
+ es = data.word(kExtras);
+ si = (0+2080+30000+(16*114));
+ cx = (0+2080+30000+(16*114)+((114+2)*2));
+describe:
+ al = data.byte(kCommand);
+ ah = 0;
+ _add(ax, ax);
+ _add(si, ax);
+ ax = es.word(si);
+ _add(ax, cx);
+ si = ax;
+ bx = ax;
+tryagain:
+ push(si);
+ findnextcolon();
+ al = es.byte(si);
+ cx = si;
+ si = pop();
+ _cmp(data.byte(kObjecttype), 1);
+ if (!flags.z())
+ return /* (cantmakeoneup) */;
+ _cmp(al, 0);
+ if (flags.z())
+ goto findsometext;
+ _cmp(al, ':');
+ if (flags.z())
+ goto findsometext;
+ return;
+findsometext:
+ searchforsame();
+ goto tryagain;
+}
+
+void DreamGenContext::searchforsame() {
+ STACK_CHECK;
+ si = cx;
+searchagain:
+ _inc(si);
+ al = es.byte(bx);
+search:
+ _cmp(es.byte(si), al);
+ if (flags.z())
+ goto gotstartletter;
+ _inc(cx);
+ _inc(si);
+ _cmp(si, 8000);
+ if (flags.c())
+ goto search;
+ si = bx;
+ ax = pop();
+ return;
+gotstartletter:
+ push(bx);
+ push(si);
+keepchecking:
+ _inc(si);
+ _inc(bx);
+ al = es.byte(bx);
+ ah = es.byte(si);
+ _cmp(al, ':');
+ if (flags.z())
+ goto foundmatch;
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundmatch;
+ _cmp(al, ah);
+ if (flags.z())
+ goto keepchecking;
+ si = pop();
+ bx = pop();
+ goto searchagain;
+foundmatch:
+ si = pop();
+ bx = pop();
+}
+
+void DreamGenContext::findnextcolon() {
+ STACK_CHECK;
+isntcolon:
+ al = es.byte(si);
+ _inc(si);
+ _cmp(al, 0);
+ if (flags.z())
+ return /* (endofcolon) */;
+ _cmp(al, ':');
+ if (!flags.z())
+ goto isntcolon;
+}
+
+void DreamGenContext::inventory() {
+ STACK_CHECK;
+ _cmp(data.byte(kMandead), 1);
+ if (flags.z())
+ goto iswatchinv;
+ _cmp(data.word(kWatchingtime), 0);
+ if (flags.z())
+ goto notwatchinv;
+iswatchinv:
+ blank();
+ return;
+notwatchinv:
+ _cmp(data.byte(kCommandtype), 239);
+ if (flags.z())
+ goto alreadyopinv;
+ data.byte(kCommandtype) = 239;
+ al = 32;
+ commandonly();
+alreadyopinv:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (cantopinv) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doopeninv;
+ return;
+doopeninv:
+ data.word(kTimecount) = 0;
+ data.byte(kPointermode) = 0;
+ data.byte(kInmaparea) = 0;
+ animpointer();
+ createpanel();
+ showpanel();
+ examicon();
+ showman();
+ showexit();
+ undertextline();
+ data.byte(kPickup) = 0;
+ data.byte(kInvopen) = 2;
+ openinv();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+ data.byte(kOpenedob) = 255;
+ goto waitexam;
+ return;
+/*continuing to unbounded code: examineagain from examineob:3-66*/
+examineagain:
+ data.byte(kInmaparea) = 0;
+ data.byte(kExamagain) = 0;
+ data.byte(kOpenedob) = 255;
+ data.byte(kOpenedtype) = 255;
+ data.byte(kInvopen) = 0;
+ al = data.byte(kCommandtype);
+ data.byte(kObjecttype) = al;
+ data.byte(kItemframe) = 0;
+ data.byte(kPointerframe) = 0;
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ obicons();
+ obpicture();
+ describeob();
+ undertextline();
+ data.byte(kCommandtype) = 255;
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+waitexam:
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ delpointer();
+ data.byte(kGetback) = 0;
+ bx = 2494;
+ _cmp(data.byte(kInvopen), 0);
+ if (flags.z())
+ goto notuseinv;
+ bx = 2556;
+ _cmp(data.byte(kInvopen), 1);
+ if (flags.z())
+ goto notuseinv;
+ bx = 2618;
+notuseinv:
+ checkcoords();
+ _cmp(data.byte(kExamagain), 0);
+ if (flags.z())
+ goto norex;
+ goto examineagain;
+norex:
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto waitexam;
+ data.byte(kPickup) = 0;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ goto iswatching;
+ _cmp(data.byte(kNewlocation), 255);
+ if (!flags.z())
+ goto justgetback;
+iswatching:
+ makemainscreen();
+ data.byte(kInvopen) = 0;
+ data.byte(kOpenedob) = 255;
+ return;
+justgetback:
+ data.byte(kInvopen) = 0;
+ data.byte(kOpenedob) = 255;
+}
+
+void DreamGenContext::setpickup() {
+ STACK_CHECK;
+ _cmp(data.byte(kObjecttype), 1);
+ if (flags.z())
+ goto cantpick;
+ _cmp(data.byte(kObjecttype), 3);
+ if (flags.z())
+ goto cantpick;
+ getanyad();
+ al = es.byte(bx+2);
+ _cmp(al, 4);
+ if (!flags.z())
+ goto canpick;
+cantpick:
+ blank();
+ return;
+canpick:
+ _cmp(data.byte(kCommandtype), 209);
+ if (flags.z())
+ goto alreadysp;
+ data.byte(kCommandtype) = 209;
+ bl = data.byte(kCommand);
+ bh = data.byte(kObjecttype);
+ al = 33;
+ commandwithob();
+alreadysp:
+ ax = data.word(kMousebutton);
+ _cmp(ax, 1);
+ if (!flags.z())
+ return /* (nosetpick) */;
+ _cmp(ax, data.word(kOldbutton));
+ if (!flags.z())
+ goto dosetpick;
+ return;
+dosetpick:
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ examicon();
+ data.byte(kPickup) = 1;
+ data.byte(kInvopen) = 2;
+ _cmp(data.byte(kObjecttype), 4);
+ if (flags.z())
+ goto pickupexob;
+ al = data.byte(kCommand);
+ data.byte(kItemframe) = al;
+ data.byte(kOpenedob) = 255;
+ transfertoex();
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = 4;
+ geteitherad();
+ es.byte(bx+2) = 20;
+ es.byte(bx+3) = 255;
+ openinv();
+ worktoscreenm();
+ return;
+pickupexob:
+ al = data.byte(kCommand);
+ data.byte(kItemframe) = al;
+ data.byte(kOpenedob) = 255;
+ openinv();
+ worktoscreenm();
+}
+
+void DreamGenContext::examinventory() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 249);
+ if (flags.z())
+ goto alreadyexinv;
+ data.byte(kCommandtype) = 249;
+ al = 32;
+ commandonly();
+alreadyexinv:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (!flags.z())
+ goto doexinv;
+ return;
+doexinv:
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ examicon();
+ data.byte(kPickup) = 0;
+ data.byte(kInvopen) = 2;
+ openinv();
+ worktoscreenm();
+}
+
+void DreamGenContext::reexfrominv() {
+ STACK_CHECK;
+ findinvpos();
+ ax = es.word(bx);
+ data.byte(kCommandtype) = ah;
+ data.byte(kCommand) = al;
+ data.byte(kExamagain) = 1;
+ data.byte(kPointermode) = 0;
+}
+
+void DreamGenContext::reexfromopen() {
+ STACK_CHECK;
+ return;
+ findopenpos();
+ ax = es.word(bx);
+ data.byte(kCommandtype) = ah;
+ data.byte(kCommand) = al;
+ data.byte(kExamagain) = 1;
+ data.byte(kPointermode) = 0;
+}
+
+void DreamGenContext::swapwithinv() {
+ STACK_CHECK;
+ al = data.byte(kItemframe);
+ ah = data.byte(kObjecttype);
+ _cmp(ax, data.word(kOldsubject));
+ if (!flags.z())
+ goto difsub7;
+ _cmp(data.byte(kCommandtype), 243);
+ if (flags.z())
+ goto alreadyswap1;
+ data.byte(kCommandtype) = 243;
+difsub7:
+ data.word(kOldsubject) = ax;
+ bx = ax;
+ al = 34;
+ commandwithob();
+alreadyswap1:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (cantswap1) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doswap1;
+ return;
+doswap1:
+ ah = data.byte(kObjecttype);
+ al = data.byte(kItemframe);
+ push(ax);
+ findinvpos();
+ ax = es.word(bx);
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = ah;
+ geteitherad();
+ es.byte(bx+2) = 20;
+ es.byte(bx+3) = 255;
+ bl = data.byte(kItemframe);
+ bh = data.byte(kObjecttype);
+ ax = pop();
+ data.byte(kObjecttype) = ah;
+ data.byte(kItemframe) = al;
+ push(bx);
+ findinvpos();
+ delpointer();
+ al = data.byte(kItemframe);
+ geteitherad();
+ es.byte(bx+2) = 4;
+ es.byte(bx+3) = 255;
+ al = data.byte(kLastinvpos);
+ es.byte(bx+4) = al;
+ ax = pop();
+ data.byte(kObjecttype) = ah;
+ data.byte(kItemframe) = al;
+ fillryan();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::swapwithopen() {
+ STACK_CHECK;
+ al = data.byte(kItemframe);
+ ah = data.byte(kObjecttype);
+ _cmp(ax, data.word(kOldsubject));
+ if (!flags.z())
+ goto difsub8;
+ _cmp(data.byte(kCommandtype), 242);
+ if (flags.z())
+ goto alreadyswap2;
+ data.byte(kCommandtype) = 242;
+difsub8:
+ data.word(kOldsubject) = ax;
+ bx = ax;
+ al = 34;
+ commandwithob();
+alreadyswap2:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (cantswap2) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doswap2;
+ return;
+doswap2:
+ geteitherad();
+ isitworn();
+ if (!flags.z())
+ goto notwornswap;
+ wornerror();
+ return;
+notwornswap:
+ delpointer();
+ al = data.byte(kItemframe);
+ _cmp(al, data.byte(kOpenedob));
+ if (!flags.z())
+ goto isntsame2;
+ al = data.byte(kObjecttype);
+ _cmp(al, data.byte(kOpenedtype));
+ if (!flags.z())
+ goto isntsame2;
+ errormessage1();
+ return;
+isntsame2:
+ checkobjectsize();
+ _cmp(al, 0);
+ if (flags.z())
+ goto sizeok2;
+ return;
+sizeok2:
+ ah = data.byte(kObjecttype);
+ al = data.byte(kItemframe);
+ push(ax);
+ findopenpos();
+ ax = es.word(bx);
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = ah;
+ _cmp(ah, 4);
+ if (!flags.z())
+ goto makeswapex;
+ geteitherad();
+ es.byte(bx+2) = 20;
+ es.byte(bx+3) = 255;
+ goto actuallyswap;
+makeswapex:
+ transfertoex();
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = 4;
+ geteitherad();
+ es.byte(bx+2) = 20;
+ es.byte(bx+3) = 255;
+actuallyswap:
+ bl = data.byte(kItemframe);
+ bh = data.byte(kObjecttype);
+ ax = pop();
+ data.byte(kObjecttype) = ah;
+ data.byte(kItemframe) = al;
+ push(bx);
+ findopenpos();
+ geteitherad();
+ al = data.byte(kOpenedtype);
+ es.byte(bx+2) = al;
+ al = data.byte(kOpenedob);
+ es.byte(bx+3) = al;
+ al = data.byte(kLastinvpos);
+ es.byte(bx+4) = al;
+ al = data.byte(kReallocation);
+ es.byte(bx+5) = al;
+ ax = pop();
+ data.byte(kObjecttype) = ah;
+ data.byte(kItemframe) = al;
+ fillopen();
+ fillryan();
+ undertextline();
+ readmouse();
+ useopened();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::intoinv() {
+ STACK_CHECK;
+ _cmp(data.byte(kPickup), 0);
+ if (!flags.z())
+ goto notout;
+ outofinv();
+ return;
+notout:
+ findinvpos();
+ ax = es.word(bx);
+ _cmp(al, 255);
+ if (flags.z())
+ goto canplace1;
+ swapwithinv();
+ return;
+canplace1:
+ al = data.byte(kItemframe);
+ ah = data.byte(kObjecttype);
+ _cmp(ax, data.word(kOldsubject));
+ if (!flags.z())
+ goto difsub1;
+ _cmp(data.byte(kCommandtype), 220);
+ if (flags.z())
+ goto alreadyplce;
+ data.byte(kCommandtype) = 220;
+difsub1:
+ data.word(kOldsubject) = ax;
+ bx = ax;
+ al = 35;
+ commandwithob();
+alreadyplce:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notletgo2) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doplace;
+ return;
+doplace:
+ delpointer();
+ al = data.byte(kItemframe);
+ getexad();
+ es.byte(bx+2) = 4;
+ es.byte(bx+3) = 255;
+ al = data.byte(kLastinvpos);
+ es.byte(bx+4) = al;
+ data.byte(kPickup) = 0;
+ fillryan();
+ readmouse();
+ showpointer();
+ outofinv();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::deletetaken() {
+ STACK_CHECK;
+ es = data.word(kFreedat);
+ ah = data.byte(kReallocation);
+ ds = data.word(kExtras);
+ si = (0+2080+30000);
+ cx = (114);
+takenloop:
+ al = ds.byte(si+11);
+ _cmp(al, ah);
+ if (!flags.z())
+ goto notinhere;
+ bl = ds.byte(si+1);
+ bh = 0;
+ _add(bx, bx);
+ _add(bx, bx);
+ _add(bx, bx);
+ _add(bx, bx);
+ es.byte(bx+2) = 254;
+notinhere:
+ _add(si, 16);
+ if (--cx)
+ goto takenloop;
+}
+
+void DreamGenContext::outofinv() {
+ STACK_CHECK;
+ findinvpos();
+ ax = es.word(bx);
+ _cmp(al, 255);
+ if (!flags.z())
+ goto canpick2;
+ blank();
+ return;
+canpick2:
+ bx = data.word(kMousebutton);
+ _cmp(bx, 2);
+ if (!flags.z())
+ goto canpick2a;
+ reexfrominv();
+ return;
+canpick2a:
+ _cmp(ax, data.word(kOldsubject));
+ if (!flags.z())
+ goto difsub3;
+ _cmp(data.byte(kCommandtype), 221);
+ if (flags.z())
+ goto alreadygrab;
+ data.byte(kCommandtype) = 221;
+difsub3:
+ data.word(kOldsubject) = ax;
+ bx = ax;
+ al = 36;
+ commandwithob();
+alreadygrab:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notletgo) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto dograb;
+ return;
+dograb:
+ delpointer();
+ data.byte(kPickup) = 1;
+ findinvpos();
+ ax = es.word(bx);
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = ah;
+ getexad();
+ es.byte(bx+2) = 20;
+ es.byte(bx+3) = 255;
+ fillryan();
+ readmouse();
+ showpointer();
+ intoinv();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::getfreead() {
+ STACK_CHECK;
+ ah = 0;
+ cl = 4;
+ _shl(ax, cl);
+ bx = ax;
+ es = data.word(kFreedat);
+}
+
+void DreamGenContext::getexad() {
+ STACK_CHECK;
+ ah = 0;
+ bx = 16;
+ _mul(bx);
+ bx = ax;
+ es = data.word(kExtras);
+ _add(bx, (0+2080+30000));
+}
+
+void DreamGenContext::geteitherad() {
+ STACK_CHECK;
+ _cmp(data.byte(kObjecttype), 4);
+ if (flags.z())
+ goto isinexlist;
+ al = data.byte(kItemframe);
+ getfreead();
+ return;
+isinexlist:
+ al = data.byte(kItemframe);
+ getexad();
+}
+
+void DreamGenContext::getanyad() {
+ STACK_CHECK;
+ _cmp(data.byte(kObjecttype), 4);
+ if (flags.z())
+ goto isex;
+ _cmp(data.byte(kObjecttype), 2);
+ if (flags.z())
+ goto isfree;
+ al = data.byte(kCommand);
+ getsetad();
+ ax = es.word(bx+4);
+ return;
+isfree:
+ al = data.byte(kCommand);
+ getfreead();
+ ax = es.word(bx+7);
+ return;
+isex:
+ al = data.byte(kCommand);
+ getexad();
+ ax = es.word(bx+7);
+}
+
+void DreamGenContext::getanyaddir() {
+ STACK_CHECK;
+ _cmp(ah, 4);
+ if (flags.z())
+ goto isex3;
+ _cmp(ah, 2);
+ if (flags.z())
+ goto isfree3;
+ getsetad();
+ return;
+isfree3:
+ getfreead();
+ return;
+isex3:
+ getexad();
+}
+
+void DreamGenContext::getopenedsize() {
+ STACK_CHECK;
+ _cmp(data.byte(kOpenedtype), 4);
+ if (flags.z())
+ goto isex2;
+ _cmp(data.byte(kOpenedtype), 2);
+ if (flags.z())
+ goto isfree2;
+ al = data.byte(kOpenedob);
+ getsetad();
+ ax = es.word(bx+3);
+ return;
+isfree2:
+ al = data.byte(kOpenedob);
+ getfreead();
+ ax = es.word(bx+7);
+ return;
+isex2:
+ al = data.byte(kOpenedob);
+ getexad();
+ ax = es.word(bx+7);
+}
+
+void DreamGenContext::getsetad() {
+ STACK_CHECK;
+ ah = 0;
+ bx = 64;
+ _mul(bx);
+ bx = ax;
+ es = data.word(kSetdat);
+}
+
+void DreamGenContext::findinvpos() {
+ STACK_CHECK;
+ cx = data.word(kMousex);
+ _sub(cx, (80));
+ bx = -1;
+findinv1:
+ _inc(bx);
+ _sub(cx, (44));
+ if (!flags.c())
+ goto findinv1;
+ cx = data.word(kMousey);
+ _sub(cx, (58));
+ _sub(bx, 5);
+findinv2:
+ _add(bx, 5);
+ _sub(cx, (44));
+ if (!flags.c())
+ goto findinv2;
+ al = data.byte(kRyanpage);
+ ah = 0;
+ cx = 10;
+ _mul(cx);
+ _add(bx, ax);
+ al = bl;
+ data.byte(kLastinvpos) = al;
+ _add(bx, bx);
+ es = data.word(kBuffers);
+ _add(bx, (0+(228*13)+32));
+}
+
+void DreamGenContext::findopenpos() {
+ STACK_CHECK;
+ cx = data.word(kMousex);
+ _sub(cx, (80));
+ bx = -1;
+findopenp1:
+ _inc(bx);
+ _sub(cx, (44));
+ if (!flags.c())
+ goto findopenp1;
+ al = bl;
+ data.byte(kLastinvpos) = al;
+ _add(bx, bx);
+ es = data.word(kBuffers);
+ _add(bx, (0+(228*13)));
+}
+
+void DreamGenContext::dropobject() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 223);
+ if (flags.z())
+ goto alreadydrop;
+ data.byte(kCommandtype) = 223;
+ _cmp(data.byte(kPickup), 0);
+ if (flags.z())
+ { blank(); return; };
+ bl = data.byte(kItemframe);
+ bh = data.byte(kObjecttype);
+ al = 37;
+ commandwithob();
+alreadydrop:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nodrop) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto dodrop;
+ return;
+dodrop:
+ geteitherad();
+ isitworn();
+ if (!flags.z())
+ goto nowornerror;
+ wornerror();
+ return;
+nowornerror:
+ _cmp(data.byte(kReallocation), 47);
+ if (flags.z())
+ goto nodrop2;
+ cl = data.byte(kRyanx);
+ _add(cl, 12);
+ ch = data.byte(kRyany);
+ _add(ch, 12);
+ checkone();
+ _cmp(cl, 2);
+ if (flags.c())
+ goto nodroperror;
+nodrop2:
+ droperror();
+ return;
+nodroperror:
+ _cmp(data.byte(kMapxsize), 64);
+ if (!flags.z())
+ goto notinlift;
+ _cmp(data.byte(kMapysize), 64);
+ if (!flags.z())
+ goto notinlift;
+ droperror();
+ return;
+notinlift:
+ al = data.byte(kItemframe);
+ ah = 4;
+ cl = 'G';
+ ch = 'U';
+ dl = 'N';
+ dh = 'A';
+ compare();
+ if (flags.z())
+ { cantdrop(); return; };
+ al = data.byte(kItemframe);
+ ah = 4;
+ cl = 'S';
+ ch = 'H';
+ dl = 'L';
+ dh = 'D';
+ compare();
+ if (flags.z())
+ { cantdrop(); return; };
+ data.byte(kObjecttype) = 4;
+ al = data.byte(kItemframe);
+ getexad();
+ es.byte(bx+2) = 0;
+ al = data.byte(kRyanx);
+ _add(al, 4);
+ cl = 4;
+ _shr(al, cl);
+ _add(al, data.byte(kMapx));
+ ah = data.byte(kRyany);
+ _add(ah, 8);
+ cl = 4;
+ _shr(ah, cl);
+ _add(ah, data.byte(kMapy));
+ es.byte(bx+3) = al;
+ es.byte(bx+5) = ah;
+ al = data.byte(kRyanx);
+ _add(al, 4);
+ _and(al, 15);
+ ah = data.byte(kRyany);
+ _add(ah, 8);
+ _and(ah, 15);
+ es.byte(bx+4) = al;
+ es.byte(bx+6) = ah;
+ data.byte(kPickup) = 0;
+ al = data.byte(kReallocation);
+ es.byte(bx) = al;
+}
+
+void DreamGenContext::droperror() {
+ STACK_CHECK;
+ data.byte(kCommandtype) = 255;
+ delpointer();
+ di = 76;
+ bx = 21;
+ al = 56;
+ dl = 240;
+ printmessage();
+ worktoscreenm();
+ cx = 50;
+ hangonp();
+ showpanel();
+ showman();
+ examicon();
+ data.byte(kCommandtype) = 255;
+ worktoscreenm();
+}
+
+void DreamGenContext::cantdrop() {
+ STACK_CHECK;
+ data.byte(kCommandtype) = 255;
+ delpointer();
+ di = 76;
+ bx = 21;
+ al = 24;
+ dl = 240;
+ printmessage();
+ worktoscreenm();
+ cx = 50;
+ hangonp();
+ showpanel();
+ showman();
+ examicon();
+ data.byte(kCommandtype) = 255;
+ worktoscreenm();
+}
+
+void DreamGenContext::wornerror() {
+ STACK_CHECK;
+ data.byte(kCommandtype) = 255;
+ delpointer();
+ di = 76;
+ bx = 21;
+ al = 57;
+ dl = 240;
+ printmessage();
+ worktoscreenm();
+ cx = 50;
+ hangonp();
+ showpanel();
+ showman();
+ examicon();
+ data.byte(kCommandtype) = 255;
+ worktoscreenm();
+}
+
+void DreamGenContext::removeobfrominv() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommand), 100);
+ if (flags.z())
+ return /* (obnotexist) */;
+ getanyad();
+ di = bx;
+ cl = data.byte(kCommand);
+ ch = 0;
+ deleteexobject();
+}
+
+void DreamGenContext::selectopenob() {
+ STACK_CHECK;
+ al = data.byte(kCommand);
+ getanyad();
+ _cmp(al, 255);
+ if (!flags.z())
+ goto canopenit1;
+ blank();
+ return;
+canopenit1:
+ _cmp(data.byte(kCommandtype), 224);
+ if (flags.z())
+ goto alreadyopob;
+ data.byte(kCommandtype) = 224;
+ bl = data.byte(kCommand);
+ bh = data.byte(kObjecttype);
+ al = 38;
+ commandwithob();
+alreadyopob:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (noopenob) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doopenob;
+ return;
+doopenob:
+ al = data.byte(kCommand);
+ data.byte(kOpenedob) = al;
+ al = data.byte(kObjecttype);
+ data.byte(kOpenedtype) = al;
+ createpanel();
+ showpanel();
+ showman();
+ examicon();
+ showexit();
+ openinv();
+ openob();
+ undertextline();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::useopened() {
+ STACK_CHECK;
+ _cmp(data.byte(kOpenedob), 255);
+ if (flags.z())
+ return /* (cannotuseopen) */;
+ _cmp(data.byte(kPickup), 0);
+ if (!flags.z())
+ goto notout2;
+ outofopen();
+ return;
+notout2:
+ findopenpos();
+ ax = es.word(bx);
+ _cmp(al, 255);
+ if (flags.z())
+ goto canplace3;
+ swapwithopen();
+ return;
+canplace3:
+ _cmp(data.byte(kPickup), 1);
+ if (flags.z())
+ goto intoopen;
+ blank();
+ return;
+intoopen:
+ al = data.byte(kItemframe);
+ ah = data.byte(kObjecttype);
+ _cmp(ax, data.word(kOldsubject));
+ if (!flags.z())
+ goto difsub2;
+ _cmp(data.byte(kCommandtype), 227);
+ if (flags.z())
+ goto alreadyplc2;
+ data.byte(kCommandtype) = 227;
+difsub2:
+ data.word(kOldsubject) = ax;
+ bx = ax;
+ al = 35;
+ commandwithob();
+alreadyplc2:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notletgo3) */;
+ _cmp(ax, 1);
+ if (flags.z())
+ goto doplace2;
+ return;
+doplace2:
+ geteitherad();
+ isitworn();
+ if (!flags.z())
+ goto notworntoopen;
+ wornerror();
+ return;
+notworntoopen:
+ delpointer();
+ al = data.byte(kItemframe);
+ _cmp(al, data.byte(kOpenedob));
+ if (!flags.z())
+ goto isntsame;
+ al = data.byte(kObjecttype);
+ _cmp(al, data.byte(kOpenedtype));
+ if (!flags.z())
+ goto isntsame;
+ errormessage1();
+ return;
+isntsame:
+ checkobjectsize();
+ _cmp(al, 0);
+ if (flags.z())
+ goto sizeok1;
+ return;
+sizeok1:
+ data.byte(kPickup) = 0;
+ al = data.byte(kItemframe);
+ geteitherad();
+ al = data.byte(kOpenedtype);
+ es.byte(bx+2) = al;
+ al = data.byte(kOpenedob);
+ es.byte(bx+3) = al;
+ al = data.byte(kLastinvpos);
+ es.byte(bx+4) = al;
+ al = data.byte(kReallocation);
+ es.byte(bx+5) = al;
+ fillopen();
+ undertextline();
+ readmouse();
+ useopened();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::errormessage1() {
+ STACK_CHECK;
+ delpointer();
+ di = 76;
+ bx = 21;
+ al = 58;
+ dl = 240;
+ printmessage();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+ cx = 50;
+ hangonp();
+ showpanel();
+ showman();
+ examicon();
+ readmouse();
+ useopened();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::errormessage2() {
+ STACK_CHECK;
+ data.byte(kCommandtype) = 255;
+ delpointer();
+ di = 76;
+ bx = 21;
+ al = 59;
+ dl = 240;
+ printmessage();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+ cx = 50;
+ hangonp();
+ showpanel();
+ showman();
+ examicon();
+ readmouse();
+ useopened();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::errormessage3() {
+ STACK_CHECK;
+ delpointer();
+ di = 76;
+ bx = 21;
+ al = 60;
+ dl = 240;
+ printmessage();
+ worktoscreenm();
+ cx = 50;
+ hangonp();
+ showpanel();
+ showman();
+ examicon();
+ readmouse();
+ useopened();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::checkobjectsize() {
+ STACK_CHECK;
+ getopenedsize();
+ push(ax);
+ al = data.byte(kItemframe);
+ geteitherad();
+ al = es.byte(bx+9);
+ cx = pop();
+ _cmp(al, 255);
+ if (!flags.z())
+ goto notunsized;
+ al = 6;
+notunsized:
+ _cmp(al, 100);
+ if (!flags.c())
+ goto specialcase;
+ _cmp(cl, 100);
+ if (flags.c())
+ goto isntspecial;
+ errormessage3();
+ goto sizewrong;
+isntspecial:
+ _cmp(cl, al);
+ if (!flags.c())
+ goto sizeok;
+specialcase:
+ _sub(al, 100);
+ _cmp(cl, 100);
+ if (!flags.c())
+ goto bothspecial;
+ _cmp(cl, al);
+ if (!flags.c())
+ goto sizeok;
+ errormessage2();
+ goto sizewrong;
+bothspecial:
+ _sub(cl, 100);
+ _cmp(al, cl);
+ if (flags.z())
+ goto sizeok;
+ errormessage3();
+sizewrong:
+ al = 1;
+ return;
+sizeok:
+ al = 0;
+}
+
+void DreamGenContext::outofopen() {
+ STACK_CHECK;
+ _cmp(data.byte(kOpenedob), 255);
+ if (flags.z())
+ goto cantuseopen;
+ findopenpos();
+ ax = es.word(bx);
+ _cmp(al, 255);
+ if (!flags.z())
+ goto canpick4;
+cantuseopen:
+ blank();
+ return;
+canpick4:
+ _cmp(ax, data.word(kOldsubject));
+ if (!flags.z())
+ goto difsub4;
+ _cmp(data.byte(kCommandtype), 228);
+ if (flags.z())
+ goto alreadygrb;
+ data.byte(kCommandtype) = 228;
+difsub4:
+ data.word(kOldsubject) = ax;
+ bx = ax;
+ al = 36;
+ commandwithob();
+alreadygrb:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notletgo4) */;
+ _cmp(ax, 1);
+ if (flags.z())
+ goto dogrb;
+ _cmp(ax, 2);
+ if (!flags.z())
+ return /* (notletgo4) */;
+ reexfromopen();
+ return;
+dogrb:
+ delpointer();
+ data.byte(kPickup) = 1;
+ findopenpos();
+ ax = es.word(bx);
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = ah;
+ _cmp(ah, 4);
+ if (!flags.z())
+ goto makeintoex;
+ geteitherad();
+ es.byte(bx+2) = 20;
+ es.byte(bx+3) = 255;
+ goto actuallyout;
+makeintoex:
+ transfertoex();
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = 4;
+ geteitherad();
+ es.byte(bx+2) = 20;
+ es.byte(bx+3) = 255;
+actuallyout:
+ fillopen();
+ undertextline();
+ readmouse();
+ useopened();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::transfertoex() {
+ STACK_CHECK;
+ emergencypurge();
+ getexpos();
+ al = data.byte(kExpos);
+ push(ax);
+ push(di);
+ al = data.byte(kItemframe);
+ ah = 0;
+ bx = 16;
+ _mul(bx);
+ ds = data.word(kFreedat);
+ si = ax;
+ cx = 8;
+ _movsw(cx, true);
+ di = pop();
+ al = data.byte(kReallocation);
+ es.byte(di) = al;
+ es.byte(di+11) = al;
+ al = data.byte(kItemframe);
+ es.byte(di+1) = al;
+ es.byte(di+2) = 4;
+ es.byte(di+3) = 255;
+ al = data.byte(kLastinvpos);
+ es.byte(di+4) = al;
+ al = data.byte(kItemframe);
+ data.byte(kItemtotran) = al;
+ transfermap();
+ transferinv();
+ transfertext();
+ al = data.byte(kItemframe);
+ ah = 0;
+ bx = 16;
+ _mul(bx);
+ ds = data.word(kFreedat);
+ si = ax;
+ ds.byte(si+2) = 254;
+ pickupconts();
+ ax = pop();
+}
+
+void DreamGenContext::pickupconts() {
+ STACK_CHECK;
+ al = ds.byte(si+7);
+ _cmp(al, 255);
+ if (flags.z())
+ return /* (notopenable) */;
+ al = data.byte(kItemframe);
+ ah = data.byte(kObjecttype);
+ dl = data.byte(kExpos);
+ es = data.word(kFreedat);
+ bx = 0;
+ cx = 0;
+pickupcontloop:
+ push(cx);
+ push(es);
+ push(bx);
+ push(dx);
+ push(ax);
+ _cmp(es.byte(bx+2), ah);
+ if (!flags.z())
+ goto notinsidethis;
+ _cmp(es.byte(bx+3), al);
+ if (!flags.z())
+ goto notinsidethis;
+ data.byte(kItemtotran) = cl;
+ transfercontoex();
+notinsidethis:
+ ax = pop();
+ dx = pop();
+ bx = pop();
+ es = pop();
+ cx = pop();
+ _add(bx, 16);
+ _inc(cx);
+ _cmp(cx, 80);
+ if (!flags.z())
+ goto pickupcontloop;
+}
+
+void DreamGenContext::transfercontoex() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ push(dx);
+ push(es);
+ push(bx);
+ getexpos();
+ si = pop();
+ ds = pop();
+ push(di);
+ cx = 8;
+ _movsw(cx, true);
+ di = pop();
+ dx = pop();
+ al = data.byte(kReallocation);
+ es.byte(di) = al;
+ es.byte(di+11) = al;
+ al = data.byte(kItemtotran);
+ es.byte(di+1) = al;
+ es.byte(di+3) = dl;
+ es.byte(di+2) = 4;
+ transfermap();
+ transferinv();
+ transfertext();
+ si = pop();
+ ds = pop();
+ ds.byte(si+2) = 255;
+}
+
+void DreamGenContext::transfertext() {
+ STACK_CHECK;
+ es = data.word(kExtras);
+ al = data.byte(kExpos);
+ ah = 0;
+ _add(ax, ax);
+ bx = (0+2080+30000+(16*114));
+ _add(bx, ax);
+ di = data.word(kExtextpos);
+ es.word(bx) = di;
+ _add(di, (0+2080+30000+(16*114)+((114+2)*2)));
+ al = data.byte(kItemtotran);
+ ah = 0;
+ _add(ax, ax);
+ ds = data.word(kFreedesc);
+ bx = (0);
+ _add(bx, ax);
+ si = (0+(82*2));
+ ax = ds.word(bx);
+ _add(si, ax);
+moretext:
+ _lodsb();
+ _stosb();
+ _inc(data.word(kExtextpos));
+ _cmp(al, 0);
+ if (!flags.z())
+ goto moretext;
+}
+
+void DreamGenContext::getexpos() {
+ STACK_CHECK;
+ es = data.word(kExtras);
+ al = 0;
+ di = (0+2080+30000);
+tryanotherex:
+ _cmp(es.byte(di+2), 255);
+ if (flags.z())
+ goto foundnewex;
+ _add(di, 16);
+ _inc(al);
+ _cmp(al, (114));
+ if (!flags.z())
+ goto tryanotherex;
+foundnewex:
+ data.byte(kExpos) = al;
+}
+
+void DreamGenContext::purgealocation() {
+ STACK_CHECK;
+ push(ax);
+ es = data.word(kExtras);
+ di = (0+2080+30000);
+ bx = pop();
+ cx = 0;
+purgeloc:
+ _cmp(bl, es.byte(di+0));
+ if (!flags.z())
+ goto dontpurge;
+ _cmp(es.byte(di+2), 0);
+ if (!flags.z())
+ goto dontpurge;
+ push(di);
+ push(es);
+ push(bx);
+ push(cx);
+ deleteexobject();
+ cx = pop();
+ bx = pop();
+ es = pop();
+ di = pop();
+dontpurge:
+ _add(di, 16);
+ _inc(cx);
+ _cmp(cx, (114));
+ if (!flags.z())
+ goto purgeloc;
+}
+
+void DreamGenContext::emergencypurge() {
+ STACK_CHECK;
+checkpurgeagain:
+ ax = data.word(kExframepos);
+ _add(ax, 4000);
+ _cmp(ax, (30000));
+ if (flags.c())
+ goto notnearframeend;
+ purgeanitem();
+ goto checkpurgeagain;
+notnearframeend:
+ ax = data.word(kExtextpos);
+ _add(ax, 400);
+ _cmp(ax, (18000));
+ if (flags.c())
+ return /* (notneartextend) */;
+ purgeanitem();
+ goto checkpurgeagain;
+}
+
+void DreamGenContext::purgeanitem() {
+ STACK_CHECK;
+ es = data.word(kExtras);
+ di = (0+2080+30000);
+ bl = data.byte(kReallocation);
+ cx = 0;
+lookforpurge:
+ al = es.byte(di+2);
+ _cmp(al, 0);
+ if (!flags.z())
+ goto cantpurge;
+ _cmp(es.byte(di+12), 2);
+ if (flags.z())
+ goto iscup;
+ _cmp(es.byte(di+12), 255);
+ if (!flags.z())
+ goto cantpurge;
+iscup:
+ _cmp(es.byte(di+11), bl);
+ if (flags.z())
+ goto cantpurge;
+ deleteexobject();
+ return;
+cantpurge:
+ _add(di, 16);
+ _inc(cx);
+ _cmp(cx, (114));
+ if (!flags.z())
+ goto lookforpurge;
+ di = (0+2080+30000);
+ bl = data.byte(kReallocation);
+ cx = 0;
+lookforpurge2:
+ al = es.byte(di+2);
+ _cmp(al, 0);
+ if (!flags.z())
+ goto cantpurge2;
+ _cmp(es.byte(di+12), 255);
+ if (!flags.z())
+ goto cantpurge2;
+ deleteexobject();
+ return;
+cantpurge2:
+ _add(di, 16);
+ _inc(cx);
+ _cmp(cx, (114));
+ if (!flags.z())
+ goto lookforpurge2;
+}
+
+void DreamGenContext::deleteexobject() {
+ STACK_CHECK;
+ push(cx);
+ push(cx);
+ push(cx);
+ push(cx);
+ al = 255;
+ cx = 16;
+ _stosb(cx, true);
+ ax = pop();
+ cl = al;
+ _add(al, al);
+ _add(al, cl);
+ deleteexframe();
+ ax = pop();
+ cl = al;
+ _add(al, al);
+ _add(al, cl);
+ _inc(al);
+ deleteexframe();
+ ax = pop();
+ deleteextext();
+ bx = pop();
+ bh = bl;
+ bl = 4;
+ di = (0+2080+30000);
+ cx = 0;
+deleteconts:
+ _cmp(es.word(di+2), bx);
+ if (!flags.z())
+ goto notinsideex;
+ push(bx);
+ push(cx);
+ push(di);
+ deleteexobject();
+ di = pop();
+ cx = pop();
+ bx = pop();
+notinsideex:
+ _add(di, 16);
+ _inc(cx);
+ _cmp(cx, (114));
+ if (!flags.z())
+ goto deleteconts;
+}
+
+void DreamGenContext::deleteexframe() {
+ STACK_CHECK;
+ di = (0);
+ ah = 0;
+ _add(ax, ax);
+ _add(di, ax);
+ _add(ax, ax);
+ _add(di, ax);
+ al = es.byte(di);
+ ah = 0;
+ cl = es.byte(di+1);
+ ch = 0;
+ _mul(cx);
+ si = es.word(di+2);
+ push(si);
+ _add(si, (0+2080));
+ cx = (30000);
+ _sub(cx, es.word(di+2));
+ di = si;
+ _add(si, ax);
+ push(ax);
+ ds = es;
+ _movsb(cx, true);
+ bx = pop();
+ _sub(data.word(kExframepos), bx);
+ si = pop();
+ cx = (114)*3;
+ di = (0);
+shuffleadsdown:
+ ax = es.word(di+2);
+ _cmp(ax, si);
+ if (flags.c())
+ goto beforethisone;
+ _sub(ax, bx);
+beforethisone:
+ es.word(di+2) = ax;
+ _add(di, 6);
+ if (--cx)
+ goto shuffleadsdown;
+}
+
+void DreamGenContext::deleteextext() {
+ STACK_CHECK;
+ di = (0+2080+30000+(16*114));
+ ah = 0;
+ _add(ax, ax);
+ _add(di, ax);
+ ax = es.word(di);
+ si = ax;
+ di = ax;
+ _add(si, (0+2080+30000+(16*114)+((114+2)*2)));
+ _add(di, (0+2080+30000+(16*114)+((114+2)*2)));
+ ax = 0;
+findlenextext:
+ cl = es.byte(si);
+ _inc(ax);
+ _inc(si);
+ _cmp(cl, 0);
+ if (!flags.z())
+ goto findlenextext;
+ cx = (18000);
+ bx = si;
+ _sub(bx, (0+2080+30000+(16*114)+((114+2)*2)));
+ push(bx);
+ push(ax);
+ _sub(cx, bx);
+ _movsb(cx, true);
+ bx = pop();
+ _sub(data.word(kExtextpos), bx);
+ si = pop();
+ cx = (114);
+ di = (0+2080+30000+(16*114));
+shuffletextads:
+ ax = es.word(di);
+ _cmp(ax, si);
+ if (flags.c())
+ goto beforethistext;
+ _sub(ax, bx);
+beforethistext:
+ es.word(di) = ax;
+ _add(di, 2);
+ if (--cx)
+ goto shuffletextads;
+}
+
+void DreamGenContext::blockget() {
+ STACK_CHECK;
+ ah = al;
+ al = 0;
+ ds = data.word(kBackdrop);
+ si = (0+192);
+ _add(si, ax);
+}
+
+void DreamGenContext::drawfloor() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ eraseoldobs();
+ drawflags();
+ calcmapad();
+ doblocks();
+ showallobs();
+ showallfree();
+ showallex();
+ paneltomap();
+ initrain();
+ data.byte(kNewobs) = 0;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::calcmapad() {
+ STACK_CHECK;
+ getdimension();
+ push(cx);
+ push(dx);
+ al = 11;
+ _sub(al, dl);
+ _sub(al, cl);
+ _sub(al, cl);
+ ax.cbw();
+ bx = 8;
+ _mul(bx);
+ _add(ax, data.word(kMapoffsetx));
+ data.word(kMapadx) = ax;
+ dx = pop();
+ cx = pop();
+ al = 10;
+ _sub(al, dh);
+ _sub(al, ch);
+ _sub(al, ch);
+ ax.cbw();
+ bx = 8;
+ _mul(bx);
+ _add(ax, data.word(kMapoffsety));
+ data.word(kMapady) = ax;
+}
+
+void DreamGenContext::getdimension() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32));
+ ch = 0;
+dimloop1:
+ addalong();
+ _cmp(al, 0);
+ if (!flags.z())
+ goto finishdim1;
+ _inc(ch);
+ goto dimloop1;
+finishdim1:
+ bx = (0+(228*13)+32+60+(32*32));
+ cl = 0;
+dimloop2:
+ push(bx);
+ addlength();
+ bx = pop();
+ _cmp(al, 0);
+ if (!flags.z())
+ goto finishdim2;
+ _inc(cl);
+ _add(bx, 3);
+ goto dimloop2;
+finishdim2:
+ bx = (0+(228*13)+32+60+(32*32))+(11*3*9);
+ dh = 10;
+dimloop3:
+ push(bx);
+ addalong();
+ bx = pop();
+ _cmp(al, 0);
+ if (!flags.z())
+ goto finishdim3;
+ _dec(dh);
+ _sub(bx, 11*3);
+ goto dimloop3;
+finishdim3:
+ bx = (0+(228*13)+32+60+(32*32))+(3*10);
+ dl = 11;
+dimloop4:
+ push(bx);
+ addlength();
+ bx = pop();
+ _cmp(al, 0);
+ if (!flags.z())
+ goto finishdim4;
+ _dec(dl);
+ _sub(bx, 3);
+ goto dimloop4;
+finishdim4:
+ al = cl;
+ ah = 0;
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ data.word(kMapxstart) = ax;
+ al = ch;
+ ah = 0;
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ data.word(kMapystart) = ax;
+ _sub(dl, cl);
+ _sub(dh, ch);
+ al = dl;
+ ah = 0;
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ data.byte(kMapxsize) = al;
+ al = dh;
+ ah = 0;
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ _shl(ax, 1);
+ data.byte(kMapysize) = al;
+}
+
+void DreamGenContext::addalong() {
+ STACK_CHECK;
+ ah = 11;
+addloop:
+ _cmp(es.byte(bx), 0);
+ if (!flags.z())
+ goto gotalong;
+ _add(bx, 3);
+ _dec(ah);
+ if (!flags.z())
+ goto addloop;
+ al = 0;
+ return;
+gotalong:
+ al = 1;
+}
+
+void DreamGenContext::addlength() {
+ STACK_CHECK;
+ ah = 10;
+addloop2:
+ _cmp(es.byte(bx), 0);
+ if (!flags.z())
+ goto gotlength;
+ _add(bx, 3*11);
+ _dec(ah);
+ if (!flags.z())
+ goto addloop2;
+ al = 0;
+ return;
+gotlength:
+ al = 1;
+}
+
+void DreamGenContext::drawflags() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32));
+ al = data.byte(kMapy);
+ ah = 0;
+ cx = (66);
+ _mul(cx);
+ bl = data.byte(kMapx);
+ bh = 0;
+ _add(ax, bx);
+ si = (0);
+ _add(si, ax);
+ cx = 10;
+_tmp28:
+ push(cx);
+ cx = 11;
+_tmp28a:
+ ds = data.word(kMapdata);
+ _lodsb();
+ ds = data.word(kBackdrop);
+ push(si);
+ push(ax);
+ ah = 0;
+ _add(ax, ax);
+ si = (0);
+ _add(si, ax);
+ _movsw();
+ ax = pop();
+ _stosb();
+ si = pop();
+ if (--cx)
+ goto _tmp28a;
+ _add(si, (66)-11);
+ cx = pop();
+ if (--cx)
+ goto _tmp28;
+}
+
+void DreamGenContext::eraseoldobs() {
+ STACK_CHECK;
+ _cmp(data.byte(kNewobs), 0);
+ if (flags.z())
+ return /* (donterase) */;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
+ cx = 16;
+oberase:
+ push(cx);
+ push(bx);
+ ax = es.word(bx+20);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ goto notthisob;
+ di = bx;
+ al = 255;
+ cx = (32);
+ _stosb(cx, true);
+notthisob:
+ bx = pop();
+ cx = pop();
+ _add(bx, (32));
+ if (--cx)
+ goto oberase;
+}
+
+void DreamGenContext::showallobs() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32));
+ data.word(kListpos) = bx;
+ di = bx;
+ cx = 128*5;
+ al = 255;
+ _stosb(cx, true);
+ es = data.word(kSetframes);
+ data.word(kFrsegment) = es;
+ ax = (0);
+ data.word(kDataad) = ax;
+ ax = (0+2080);
+ data.word(kFramesad) = ax;
+ data.byte(kCurrentob) = 0;
+ ds = data.word(kSetdat);
+ si = 0;
+ cx = 128;
+showobsloop:
+ push(cx);
+ push(si);
+ push(si);
+ _add(si, 58);
+ es = data.word(kSetdat);
+ getmapad();
+ si = pop();
+ _cmp(ch, 0);
+ if (flags.z())
+ goto blankframe;
+ al = es.byte(si+18);
+ ah = 0;
+ data.word(kCurrentframe) = ax;
+ _cmp(al, 255);
+ if (flags.z())
+ goto blankframe;
+ push(es);
+ push(si);
+ calcfrframe();
+ finalframe();
+ si = pop();
+ es = pop();
+ al = es.byte(si+18);
+ es.byte(si+17) = al;
+ _cmp(es.byte(si+8), 0);
+ if (!flags.z())
+ goto animating;
+ _cmp(es.byte(si+5), 5);
+ if (flags.z())
+ goto animating;
+ _cmp(es.byte(si+5), 6);
+ if (flags.z())
+ goto animating;
+ ax = data.word(kCurrentframe);
+ ah = 0;
+ _add(di, data.word(kMapadx));
+ _add(bx, data.word(kMapady));
+ showframe();
+ goto drawnsetob;
+animating:
+ makebackob();
+drawnsetob:
+ si = data.word(kListpos);
+ es = data.word(kBuffers);
+ al = data.byte(kSavex);
+ ah = data.byte(kSavey);
+ es.word(si) = ax;
+ cx = ax;
+ ax = data.word(kSavesize);
+ _add(al, cl);
+ _add(ah, ch);
+ es.word(si+2) = ax;
+ al = data.byte(kCurrentob);
+ es.byte(si+4) = al;
+ _add(si, 5);
+ data.word(kListpos) = si;
+blankframe:
+ _inc(data.byte(kCurrentob));
+ si = pop();
+ cx = pop();
+ _add(si, 64);
+ _dec(cx);
+ if (flags.z())
+ return /* (finishedsetobs) */;
+ goto showobsloop;
+}
+
+void DreamGenContext::makebackob() {
+ STACK_CHECK;
+ _cmp(data.byte(kNewobs), 0);
+ if (flags.z())
+ return /* (nomake) */;
+ al = es.byte(si+5);
+ ah = es.byte(si+8);
+ push(si);
+ push(ax);
+ push(si);
+ ax = data.word(kObjectx);
+ bx = data.word(kObjecty);
+ ah = bl;
+ si = ax;
+ cx = 49520;
+ dx = data.word(kSetframes);
+ di = (0);
+ makesprite();
+ ax = pop();
+ es.word(bx+20) = ax;
+ ax = pop();
+ _cmp(al, 255);
+ if (!flags.z())
+ goto usedpriority;
+ al = 0;
+usedpriority:
+ es.byte(bx+23) = al;
+ es.byte(bx+30) = ah;
+ es.byte(bx+16) = 0;
+ es.byte(bx+18) = 0;
+ es.byte(bx+19) = 0;
+ si = pop();
+}
+
+void DreamGenContext::showallfree() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5));
+ data.word(kListpos) = bx;
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5));
+ cx = 80*5;
+ al = 255;
+ _stosb(cx, true);
+ es = data.word(kFreeframes);
+ data.word(kFrsegment) = es;
+ ax = (0);
+ data.word(kDataad) = ax;
+ ax = (0+2080);
+ data.word(kFramesad) = ax;
+ al = 0;
+ data.byte(kCurrentfree) = al;
+ ds = data.word(kFreedat);
+ si = 2;
+ cx = 0;
+loop127:
+ push(cx);
+ push(si);
+ push(si);
+ es = data.word(kFreedat);
+ getmapad();
+ si = pop();
+ _cmp(ch, 0);
+ if (flags.z())
+ goto over138;
+ al = data.byte(kCurrentfree);
+ ah = 0;
+ dx = ax;
+ _add(ax, ax);
+ _add(ax, dx);
+ data.word(kCurrentframe) = ax;
+ push(es);
+ push(si);
+ calcfrframe();
+ es = data.word(kMapstore);
+ ds = data.word(kFrsegment);
+ finalframe();
+ si = pop();
+ es = pop();
+ _cmp(cx, 0);
+ if (flags.z())
+ goto over138;
+ ax = data.word(kCurrentframe);
+ ah = 0;
+ _add(di, data.word(kMapadx));
+ _add(bx, data.word(kMapady));
+ showframe();
+ si = data.word(kListpos);
+ es = data.word(kBuffers);
+ al = data.byte(kSavex);
+ ah = data.byte(kSavey);
+ es.word(si) = ax;
+ cx = ax;
+ ax = data.word(kSavesize);
+ _add(al, cl);
+ _add(ah, ch);
+ es.word(si+2) = ax;
+ ax = pop();
+ cx = pop();
+ push(cx);
+ push(ax);
+ es.byte(si+4) = cl;
+ _add(si, 5);
+ data.word(kListpos) = si;
+over138:
+ _inc(data.byte(kCurrentfree));
+ si = pop();
+ cx = pop();
+ _add(si, 16);
+ _inc(cx);
+ _cmp(cx, 80);
+ if (flags.z())
+ return /* (finfree) */;
+ goto loop127;
+}
+
+void DreamGenContext::showallex() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5));
+ data.word(kListpos) = bx;
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5));
+ cx = 100*5;
+ al = 255;
+ _stosb(cx, true);
+ es = data.word(kExtras);
+ data.word(kFrsegment) = es;
+ ax = (0);
+ data.word(kDataad) = ax;
+ ax = (0+2080);
+ data.word(kFramesad) = ax;
+ data.byte(kCurrentex) = 0;
+ si = (0+2080+30000)+2;
+ cx = 0;
+exloop:
+ push(cx);
+ push(si);
+ es = data.word(kExtras);
+ push(si);
+ ch = 0;
+ _cmp(es.byte(si), 255);
+ if (flags.z())
+ goto notinroom;
+ al = es.byte(si-2);
+ _cmp(al, data.byte(kReallocation));
+ if (!flags.z())
+ goto notinroom;
+ getmapad();
+notinroom:
+ si = pop();
+ _cmp(ch, 0);
+ if (flags.z())
+ goto blankex;
+ al = data.byte(kCurrentex);
+ ah = 0;
+ dx = ax;
+ _add(ax, ax);
+ _add(ax, dx);
+ data.word(kCurrentframe) = ax;
+ push(es);
+ push(si);
+ calcfrframe();
+ es = data.word(kMapstore);
+ ds = data.word(kFrsegment);
+ finalframe();
+ si = pop();
+ es = pop();
+ _cmp(cx, 0);
+ if (flags.z())
+ goto blankex;
+ ax = data.word(kCurrentframe);
+ ah = 0;
+ _add(di, data.word(kMapadx));
+ _add(bx, data.word(kMapady));
+ showframe();
+ si = data.word(kListpos);
+ es = data.word(kBuffers);
+ al = data.byte(kSavex);
+ ah = data.byte(kSavey);
+ es.word(si) = ax;
+ cx = ax;
+ ax = data.word(kSavesize);
+ _add(al, cl);
+ _add(ah, ch);
+ es.word(si+2) = ax;
+ ax = pop();
+ cx = pop();
+ push(cx);
+ push(ax);
+ es.byte(si+4) = cl;
+ _add(si, 5);
+ data.word(kListpos) = si;
+blankex:
+ _inc(data.byte(kCurrentex));
+ si = pop();
+ cx = pop();
+ _add(si, 16);
+ _inc(cx);
+ _cmp(cx, 100);
+ if (flags.z())
+ return /* (finex) */;
+ goto exloop;
+}
+
+void DreamGenContext::calcfrframe() {
+ STACK_CHECK;
+ dx = data.word(kFrsegment);
+ ax = data.word(kFramesad);
+ push(ax);
+ cx = data.word(kDataad);
+ ax = data.word(kCurrentframe);
+ ds = dx;
+ bx = 6;
+ _mul(bx);
+ _add(ax, cx);
+ bx = ax;
+ cx = ds.word(bx);
+ ax = ds.word(bx+2);
+ dx = ds.word(bx+4);
+ bx = pop();
+ push(dx);
+ _add(ax, bx);
+ data.word(kSavesource) = ax;
+ data.word(kSavesize) = cx;
+ ax = pop();
+ push(ax);
+ ah = 0;
+ data.word(kOffsetx) = ax;
+ ax = pop();
+ al = ah;
+ ah = 0;
+ data.word(kOffsety) = ax;
+ return;
+ ax = pop();
+ cx = 0;
+ data.word(kSavesize) = cx;
+}
+
+void DreamGenContext::finalframe() {
+ STACK_CHECK;
+ ax = data.word(kObjecty);
+ _add(ax, data.word(kOffsety));
+ bx = data.word(kObjectx);
+ _add(bx, data.word(kOffsetx));
+ data.byte(kSavex) = bl;
+ data.byte(kSavey) = al;
+ di = data.word(kObjectx);
+ bx = data.word(kObjecty);
+}
+
+void DreamGenContext::adjustlen() {
+ STACK_CHECK;
+ ah = al;
+ _add(al, ch);
+ _cmp(al, 100);
+ if (flags.c())
+ return /* (over242) */;
+ al = 224;
+ _sub(al, ch);
+ ch = al;
+}
+
+void DreamGenContext::getmapad() {
+ STACK_CHECK;
+ getxad();
+ _cmp(ch, 0);
+ if (flags.z())
+ return /* (over146) */;
+ data.word(kObjectx) = ax;
+ getyad();
+ _cmp(ch, 0);
+ if (flags.z())
+ return /* (over146) */;
+ data.word(kObjecty) = ax;
+ ch = 1;
+}
+
+void DreamGenContext::getxad() {
+ STACK_CHECK;
+ cl = es.byte(si);
+ _inc(si);
+ al = es.byte(si);
+ _inc(si);
+ ah = es.byte(si);
+ _inc(si);
+ _cmp(cl, 0);
+ if (!flags.z())
+ goto over148;
+ _sub(al, data.byte(kMapx));
+ if (flags.c())
+ goto over148;
+ _cmp(al, 11);
+ if (!flags.c())
+ goto over148;
+ cl = 4;
+ _shl(al, cl);
+ _or(al, ah);
+ ah = 0;
+ ch = 1;
+ return;
+over148:
+ ch = 0;
+}
+
+void DreamGenContext::getyad() {
+ STACK_CHECK;
+ al = es.byte(si);
+ _inc(si);
+ ah = es.byte(si);
+ _inc(si);
+ _sub(al, data.byte(kMapy));
+ if (flags.c())
+ goto over147;
+ _cmp(al, 10);
+ if (!flags.c())
+ goto over147;
+ cl = 4;
+ _shl(al, cl);
+ _or(al, ah);
+ ah = 0;
+ ch = 1;
+ return;
+over147:
+ ch = 0;
+}
+
+void DreamGenContext::autolook() {
+ STACK_CHECK;
+ ax = data.word(kMousex);
+ _cmp(ax, data.word(kOldx));
+ if (!flags.z())
+ goto diffmouse;
+ ax = data.word(kMousey);
+ _cmp(ax, data.word(kOldy));
+ if (!flags.z())
+ goto diffmouse;
+ _dec(data.word(kLookcounter));
+ _cmp(data.word(kLookcounter), 0);
+ if (!flags.z())
+ return /* (noautolook) */;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ return /* (noautolook) */;
+ dolook();
+ return;
+diffmouse:
+ data.word(kLookcounter) = 1000;
+}
+
+void DreamGenContext::look() {
+ STACK_CHECK;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kPointermode), 2);
+ if (flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 241);
+ if (flags.z())
+ goto alreadylook;
+ data.byte(kCommandtype) = 241;
+ al = 25;
+ commandonly();
+alreadylook:
+ _cmp(data.word(kMousebutton), 1);
+ if (!flags.z())
+ return /* (nolook) */;
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nolook) */;
+ dolook();
+}
+
+void DreamGenContext::dolook() {
+ STACK_CHECK;
+ createpanel();
+ showicon();
+ undertextline();
+ worktoscreenm();
+ data.byte(kCommandtype) = 255;
+ dumptextline();
+ bl = data.byte(kRoomnum);
+ _and(bl, 31);
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kRoomdesc);
+ _add(bx, (0));
+ si = es.word(bx);
+ _add(si, (0+(38*2)));
+ findnextcolon();
+ di = 66;
+ _cmp(data.byte(kReallocation), 50);
+ if (flags.c())
+ goto notdream3;
+ di = 40;
+notdream3:
+ bx = 80;
+ dl = 241;
+ printslow();
+ _cmp(al, 1);
+ if (flags.z())
+ goto afterlook;
+ cx = 400;
+ hangonp();
+afterlook:
+ data.byte(kPointermode) = 0;
+ data.byte(kCommandtype) = 0;
+ redrawmainscrn();
+ worktoscreenm();
+}
+
+void DreamGenContext::redrawmainscrn() {
+ STACK_CHECK;
+ data.word(kTimecount) = 0;
+ createpanel();
+ data.byte(kNewobs) = 0;
+ drawfloor();
+ printsprites();
+ reelsonscreen();
+ showicon();
+ getunderzoom();
+ undertextline();
+ readmouse();
+ data.byte(kCommandtype) = 255;
+}
+
+void DreamGenContext::getback1() {
+ STACK_CHECK;
+ _cmp(data.byte(kPickup), 0);
+ if (flags.z())
+ goto notgotobject;
+ blank();
+ return;
+notgotobject:
+ _cmp(data.byte(kCommandtype), 202);
+ if (flags.z())
+ goto alreadyget;
+ data.byte(kCommandtype) = 202;
+ al = 26;
+ commandonly();
+alreadyget:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nogetback) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto dogetback;
+ return;
+dogetback:
+ data.byte(kGetback) = 1;
+ data.byte(kPickup) = 0;
+}
+
+void DreamGenContext::talk() {
+ STACK_CHECK;
+ data.byte(kTalkpos) = 0;
+ data.byte(kInmaparea) = 0;
+ al = data.byte(kCommand);
+ data.byte(kCharacter) = al;
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ undertextline();
+ convicons();
+ starttalk();
+ data.byte(kCommandtype) = 255;
+ readmouse();
+ showpointer();
+ worktoscreen();
+waittalk:
+ delpointer();
+ readmouse();
+ animpointer();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ data.byte(kGetback) = 0;
+ bx = 2660;
+ checkcoords();
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ goto finishtalk;
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto waittalk;
+finishtalk:
+ bx = data.word(kPersondata);
+ es = cs;
+ _cmp(data.byte(kTalkpos), 4);
+ if (flags.c())
+ goto notnexttalk;
+ al = es.byte(bx+7);
+ _or(al, 128);
+ es.byte(bx+7) = al;
+notnexttalk:
+ redrawmainscrn();
+ worktoscreenm();
+ _cmp(data.byte(kSpeechloaded), 1);
+ if (!flags.z())
+ return /* (nospeech) */;
+ cancelch1();
+ data.byte(kVolumedirection) = -1;
+ data.byte(kVolumeto) = 0;
+}
+
+void DreamGenContext::convicons() {
+ STACK_CHECK;
+ al = data.byte(kCharacter);
+ _and(al, 127);
+ getpersframe();
+ di = 234;
+ bx = 2;
+ data.word(kCurrentframe) = ax;
+ findsource();
+ ax = data.word(kCurrentframe);
+ _sub(ax, data.word(kTakeoff));
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::getpersframe() {
+ STACK_CHECK;
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ es = data.word(kPeople);
+ _add(bx, (0));
+ ax = es.word(bx);
+}
+
+void DreamGenContext::starttalk() {
+ STACK_CHECK;
+ data.byte(kTalkmode) = 0;
+ al = data.byte(kCharacter);
+ _and(al, 127);
+ getpersontext();
+ data.word(kCharshift) = 91+91;
+ di = 66;
+ bx = 64;
+ dl = 241;
+ al = 0;
+ ah = 79;
+ printdirect();
+ data.word(kCharshift) = 0;
+ di = 66;
+ bx = 80;
+ dl = 241;
+ al = 0;
+ ah = 0;
+ printdirect();
+ data.byte(kSpeechloaded) = 0;
+ al = data.byte(kCharacter);
+ _and(al, 127);
+ ah = 0;
+ cx = 64;
+ _mul(cx);
+ cl = 'C';
+ dl = 'R';
+ dh = data.byte(kReallocation);
+ loadspeech();
+ _cmp(data.byte(kSpeechloaded), 1);
+ if (!flags.z())
+ return /* (nospeech1) */;
+ data.byte(kVolumedirection) = 1;
+ data.byte(kVolumeto) = 6;
+ al = 50+12;
+ playchannel1();
+}
+
+void DreamGenContext::getpersontext() {
+ STACK_CHECK;
+ ah = 0;
+ cx = 64*2;
+ _mul(cx);
+ si = ax;
+ es = data.word(kPeople);
+ _add(si, (0+24));
+ cx = (0+24+(1026*2));
+ ax = es.word(si);
+ _add(ax, cx);
+ si = ax;
+}
+
+void DreamGenContext::moretalk() {
+ STACK_CHECK;
+ _cmp(data.byte(kTalkmode), 0);
+ if (flags.z())
+ goto canmore;
+ redes();
+ return;
+canmore:
+ _cmp(data.byte(kCommandtype), 215);
+ if (flags.z())
+ goto alreadymore;
+ data.byte(kCommandtype) = 215;
+ al = 49;
+ commandonly();
+alreadymore:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nomore) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto domoretalk;
+ return;
+domoretalk:
+ data.byte(kTalkmode) = 2;
+ data.byte(kTalkpos) = 4;
+ _cmp(data.byte(kCharacter), 100);
+ if (flags.c())
+ goto notsecondpart;
+ data.byte(kTalkpos) = 48;
+notsecondpart:
+ dosometalk();
+}
+
+void DreamGenContext::dosometalk() {
+ STACK_CHECK;
+dospeech:
+ al = data.byte(kTalkpos);
+ al = data.byte(kCharacter);
+ _and(al, 127);
+ ah = 0;
+ cx = 64;
+ _mul(cx);
+ cx = ax;
+ al = data.byte(kTalkpos);
+ ah = 0;
+ _add(ax, cx);
+ _add(ax, ax);
+ si = ax;
+ es = data.word(kPeople);
+ _add(si, (0+24));
+ cx = (0+24+(1026*2));
+ ax = es.word(si);
+ _add(ax, cx);
+ si = ax;
+ _cmp(es.byte(si), 0);
+ if (flags.z())
+ goto endheartalk;
+ push(es);
+ push(si);
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ convicons();
+ si = pop();
+ es = pop();
+ di = 164;
+ bx = 64;
+ dl = 144;
+ al = 0;
+ ah = 0;
+ printdirect();
+ al = data.byte(kCharacter);
+ _and(al, 127);
+ ah = 0;
+ cx = 64;
+ _mul(cx);
+ cl = data.byte(kTalkpos);
+ ch = 0;
+ _add(ax, cx);
+ cl = 'C';
+ dl = 'R';
+ dh = data.byte(kReallocation);
+ loadspeech();
+ _cmp(data.byte(kSpeechloaded), 0);
+ if (flags.z())
+ goto noplay1;
+ al = 62;
+ playchannel1();
+noplay1:
+ data.byte(kPointermode) = 3;
+ worktoscreenm();
+ cx = 180;
+ hangonpq();
+ if (!flags.c())
+ goto _tmp1;
+ return;
+_tmp1:
+ _inc(data.byte(kTalkpos));
+ al = data.byte(kTalkpos);
+ al = data.byte(kCharacter);
+ _and(al, 127);
+ ah = 0;
+ cx = 64;
+ _mul(cx);
+ cx = ax;
+ al = data.byte(kTalkpos);
+ ah = 0;
+ _add(ax, cx);
+ _add(ax, ax);
+ si = ax;
+ es = data.word(kPeople);
+ _add(si, (0+24));
+ cx = (0+24+(1026*2));
+ ax = es.word(si);
+ _add(ax, cx);
+ si = ax;
+ _cmp(es.byte(si), 0);
+ if (flags.z())
+ goto endheartalk;
+ _cmp(es.byte(si), ':');
+ if (flags.z())
+ goto skiptalk2;
+ _cmp(es.byte(si), 32);
+ if (flags.z())
+ goto skiptalk2;
+ push(es);
+ push(si);
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ convicons();
+ si = pop();
+ es = pop();
+ di = 48;
+ bx = 128;
+ dl = 144;
+ al = 0;
+ ah = 0;
+ printdirect();
+ al = data.byte(kCharacter);
+ _and(al, 127);
+ ah = 0;
+ cx = 64;
+ _mul(cx);
+ cl = data.byte(kTalkpos);
+ ch = 0;
+ _add(ax, cx);
+ cl = 'C';
+ dl = 'R';
+ dh = data.byte(kReallocation);
+ loadspeech();
+ _cmp(data.byte(kSpeechloaded), 0);
+ if (flags.z())
+ goto noplay2;
+ al = 62;
+ playchannel1();
+noplay2:
+ data.byte(kPointermode) = 3;
+ worktoscreenm();
+ cx = 180;
+ hangonpq();
+ if (!flags.c())
+ goto skiptalk2;
+ return;
+skiptalk2:
+ _inc(data.byte(kTalkpos));
+ goto dospeech;
+endheartalk:
+ data.byte(kPointermode) = 0;
+}
+
+void DreamGenContext::hangonpq() {
+ STACK_CHECK;
+ data.byte(kGetback) = 0;
+ bx = 0;
+hangloopq:
+ push(cx);
+ push(bx);
+ delpointer();
+ readmouse();
+ animpointer();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ bx = 2692;
+ checkcoords();
+ bx = pop();
+ cx = pop();
+ _cmp(data.byte(kGetback), 1);
+ if (flags.z())
+ goto quitconv;
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ goto quitconv;
+ _cmp(data.byte(kSpeechloaded), 1);
+ if (!flags.z())
+ goto notspeaking;
+ _cmp(data.byte(kCh1playing), 255);
+ if (!flags.z())
+ goto notspeaking;
+ _inc(bx);
+ _cmp(bx, 40);
+ if (flags.z())
+ goto finishconv;
+notspeaking:
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ goto hangloopq;
+ _cmp(data.word(kOldbutton), 0);
+ if (!flags.z())
+ goto hangloopq;
+finishconv:
+ delpointer();
+ data.byte(kPointermode) = 0;
+ flags._c = false;
+ return;
+quitconv:
+ delpointer();
+ data.byte(kPointermode) = 0;
+ cancelch1();
+ flags._c = true;
+ }
+
+void DreamGenContext::redes() {
+ STACK_CHECK;
+ _cmp(data.byte(kCh1playing), 255);
+ if (!flags.z())
+ goto cantredes;
+ _cmp(data.byte(kTalkmode), 2);
+ if (flags.z())
+ goto canredes;
+cantredes:
+ blank();
+ return;
+canredes:
+ _cmp(data.byte(kCommandtype), 217);
+ if (flags.z())
+ goto alreadyreds;
+ data.byte(kCommandtype) = 217;
+ al = 50;
+ commandonly();
+alreadyreds:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (!flags.z())
+ goto doredes;
+ return;
+doredes:
+ delpointer();
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ convicons();
+ starttalk();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::newplace() {
+ STACK_CHECK;
+ _cmp(data.byte(kNeedtotravel), 1);
+ if (flags.z())
+ goto istravel;
+ _cmp(data.byte(kAutolocation), -1);
+ if (!flags.z())
+ goto isautoloc;
+ return;
+isautoloc:
+ al = data.byte(kAutolocation);
+ data.byte(kNewlocation) = al;
+ data.byte(kAutolocation) = -1;
+ return;
+istravel:
+ data.byte(kNeedtotravel) = 0;
+ selectlocation();
+}
+
+void DreamGenContext::selectlocation() {
+ STACK_CHECK;
+ data.byte(kInmaparea) = 0;
+ clearbeforeload();
+ data.byte(kGetback) = 0;
+ data.byte(kPointerframe) = 22;
+ readcitypic();
+ showcity();
+ getridoftemp();
+ readdesticon();
+ loadtraveltext();
+ showpanel();
+ showman();
+ showarrows();
+ showexit();
+ locationpic();
+ undertextline();
+ data.byte(kCommandtype) = 255;
+ readmouse();
+ data.byte(kPointerframe) = 0;
+ showpointer();
+ worktoscreen();
+ al = 9;
+ ah = 255;
+ playchannel0();
+ data.byte(kNewlocation) = 255;
+select:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ goto quittravel;
+ delpointer();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ _cmp(data.byte(kGetback), 1);
+ if (flags.z())
+ goto quittravel;
+ bx = 2714;
+ checkcoords();
+ _cmp(data.byte(kNewlocation), 255);
+ if (flags.z())
+ goto select;
+ al = data.byte(kNewlocation);
+ _cmp(al, data.byte(kLocation));
+ if (flags.z())
+ goto quittravel;
+ getridoftemp();
+ getridoftemp2();
+ getridoftemp3();
+ es = data.word(kTraveltext);
+ deallocatemem();
+ return;
+quittravel:
+ al = data.byte(kReallocation);
+ data.byte(kNewlocation) = al;
+ data.byte(kGetback) = 0;
+ getridoftemp();
+ getridoftemp2();
+ getridoftemp3();
+ es = data.word(kTraveltext);
+ deallocatemem();
+}
+
+void DreamGenContext::showcity() {
+ STACK_CHECK;
+ clearwork();
+ ds = data.word(kTempgraphics);
+ di = 57;
+ bx = 32;
+ al = 0;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = 120+57;
+ bx = 32;
+ al = 1;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::lookatplace() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 224);
+ if (flags.z())
+ goto alreadyinfo;
+ data.byte(kCommandtype) = 224;
+ al = 27;
+ commandonly();
+alreadyinfo:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (flags.z())
+ return /* (noinfo) */;
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (noinfo) */;
+ bl = data.byte(kDestpos);
+ _cmp(bl, 15);
+ if (!flags.c())
+ return /* (noinfo) */;
+ push(bx);
+ delpointer();
+ deltextline();
+ getundercentre();
+ ds = data.word(kTempgraphics3);
+ al = 0;
+ ah = 0;
+ di = 60;
+ bx = 72;
+ showframe();
+ al = 4;
+ ah = 0;
+ di = 60;
+ bx = 72+55;
+ showframe();
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ al = 4;
+ ah = 0;
+ di = 60;
+ bx = 72+55+21;
+ showframe();
+_tmp1:
+ bx = pop();
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kTraveltext);
+ si = es.word(bx);
+ _add(si, (66*2));
+ findnextcolon();
+ di = 63;
+ bx = 84;
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp2;
+ bx = 84+4;
+_tmp2:
+ dl = 191;
+ al = 0;
+ ah = 0;
+ printdirect();
+ worktoscreenm();
+ cx = 500;
+ hangonp();
+ data.byte(kPointermode) = 0;
+ data.byte(kPointerframe) = 0;
+ putundercentre();
+ worktoscreenm();
+}
+
+void DreamGenContext::getundercentre() {
+ STACK_CHECK;
+ di = 58;
+ bx = 72;
+ ds = data.word(kMapstore);
+ si = 0;
+ cl = 254;
+ ch = 110;
+ multiget();
+}
+
+void DreamGenContext::putundercentre() {
+ STACK_CHECK;
+ di = 58;
+ bx = 72;
+ ds = data.word(kMapstore);
+ si = 0;
+ cl = 254;
+ ch = 110;
+ multiput();
+}
+
+void DreamGenContext::locationpic() {
+ STACK_CHECK;
+ getdestinfo();
+ al = es.byte(si);
+ push(es);
+ push(si);
+ di = 0;
+ _cmp(al, 6);
+ if (!flags.c())
+ goto secondlot;
+ ds = data.word(kTempgraphics);
+ _add(al, 4);
+ goto gotgraphic;
+secondlot:
+ _sub(al, 6);
+ ds = data.word(kTempgraphics2);
+gotgraphic:
+ _add(di, 104);
+ bx = 138+14;
+ ah = 0;
+ showframe();
+ si = pop();
+ es = pop();
+ al = data.byte(kDestpos);
+ _cmp(al, data.byte(kReallocation));
+ if (!flags.z())
+ goto notinthisone;
+ al = 3;
+ di = 104;
+ bx = 140+14;
+ ds = data.word(kTempgraphics);
+ ah = 0;
+ showframe();
+notinthisone:
+ bl = data.byte(kDestpos);
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kTraveltext);
+ si = es.word(bx);
+ _add(si, (66*2));
+ di = 50;
+ bx = 20;
+ dl = 241;
+ al = 0;
+ ah = 0;
+ printdirect();
+}
+
+void DreamGenContext::getdestinfo() {
+ STACK_CHECK;
+ al = data.byte(kDestpos);
+ ah = 0;
+ push(ax);
+ dx = data;
+ es = dx;
+ si = 8011;
+ _add(si, ax);
+ cl = es.byte(si);
+ ax = pop();
+ push(cx);
+ dx = data;
+ es = dx;
+ si = 8027;
+ _add(si, ax);
+ ax = pop();
+}
+
+void DreamGenContext::showarrows() {
+ STACK_CHECK;
+ di = 116-12;
+ bx = 16;
+ ds = data.word(kTempgraphics);
+ al = 0;
+ ah = 0;
+ showframe();
+ di = 226+12;
+ bx = 16;
+ ds = data.word(kTempgraphics);
+ al = 1;
+ ah = 0;
+ showframe();
+ di = 280;
+ bx = 14;
+ ds = data.word(kTempgraphics);
+ al = 2;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::nextdest() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 218);
+ if (flags.z())
+ goto alreadydu;
+ data.byte(kCommandtype) = 218;
+ al = 28;
+ commandonly();
+alreadydu:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (flags.z())
+ return /* (nodu) */;
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nodu) */;
+searchdestup:
+ _inc(data.byte(kDestpos));
+ _cmp(data.byte(kDestpos), 15);
+ if (!flags.z())
+ goto notlastdest;
+ data.byte(kDestpos) = 0;
+notlastdest:
+ getdestinfo();
+ _cmp(al, 0);
+ if (flags.z())
+ goto searchdestup;
+ data.byte(kNewtextline) = 1;
+ deltextline();
+ delpointer();
+ showpanel();
+ showman();
+ showarrows();
+ locationpic();
+ undertextline();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::lastdest() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 219);
+ if (flags.z())
+ goto alreadydd;
+ data.byte(kCommandtype) = 219;
+ al = 29;
+ commandonly();
+alreadydd:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (flags.z())
+ return /* (nodd) */;
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nodd) */;
+searchdestdown:
+ _dec(data.byte(kDestpos));
+ _cmp(data.byte(kDestpos), -1);
+ if (!flags.z())
+ goto notfirstdest;
+ data.byte(kDestpos) = 15;
+notfirstdest:
+ getdestinfo();
+ _cmp(al, 0);
+ if (flags.z())
+ goto searchdestdown;
+ data.byte(kNewtextline) = 1;
+ deltextline();
+ delpointer();
+ showpanel();
+ showman();
+ showarrows();
+ locationpic();
+ undertextline();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::destselect() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 222);
+ if (flags.z())
+ goto alreadytrav;
+ data.byte(kCommandtype) = 222;
+ al = 30;
+ commandonly();
+alreadytrav:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (flags.z())
+ return /* (notrav) */;
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notrav) */;
+ getdestinfo();
+ al = data.byte(kDestpos);
+ data.byte(kNewlocation) = al;
+}
+
+void DreamGenContext::getlocation() {
+ STACK_CHECK;
+ ah = 0;
+ bx = ax;
+ dx = data;
+ es = dx;
+ _add(bx, 8011);
+ al = es.byte(bx);
+}
+
+void DreamGenContext::setlocation() {
+ STACK_CHECK;
+ ah = 0;
+ bx = ax;
+ dx = data;
+ es = dx;
+ _add(bx, 8011);
+ es.byte(bx) = 1;
+}
+
+void DreamGenContext::resetlocation() {
+ STACK_CHECK;
+ push(ax);
+ _cmp(al, 5);
+ if (!flags.z())
+ goto notdelhotel;
+ purgealocation();
+ al = 21;
+ purgealocation();
+ al = 22;
+ purgealocation();
+ al = 27;
+ purgealocation();
+ goto clearedlocations;
+notdelhotel:
+ _cmp(al, 8);
+ if (!flags.z())
+ goto notdeltvstud;
+ purgealocation();
+ al = 28;
+ purgealocation();
+ goto clearedlocations;
+notdeltvstud:
+ _cmp(al, 6);
+ if (!flags.z())
+ goto notdelsarters;
+ purgealocation();
+ al = 20;
+ purgealocation();
+ al = 25;
+ purgealocation();
+ goto clearedlocations;
+notdelsarters:
+ _cmp(al, 13);
+ if (!flags.z())
+ goto notdelboathouse;
+ purgealocation();
+ al = 29;
+ purgealocation();
+ goto clearedlocations;
+notdelboathouse:
+clearedlocations:
+ ax = pop();
+ ah = 0;
+ bx = ax;
+ dx = data;
+ es = dx;
+ _add(bx, 8011);
+ es.byte(bx) = 0;
+}
+
+void DreamGenContext::readdesticon() {
+ STACK_CHECK;
+ dx = 2013;
+ loadintotemp();
+ dx = 2026;
+ loadintotemp2();
+ dx = 1961;
+ loadintotemp3();
+}
+
+void DreamGenContext::readcitypic() {
+ STACK_CHECK;
+ dx = 2000;
+ loadintotemp();
+}
+
+void DreamGenContext::usemon() {
+ STACK_CHECK;
+ data.byte(kLasttrigger) = 0;
+ es = cs;
+ di = 2970+1;
+ cx = 12;
+ al = 32;
+ _stosb(cx, true);
+ es = cs;
+ di = 2942+1;
+ cx = 12;
+ al = 32;
+ _stosb(cx, true);
+ es = cs;
+ di = 2836;
+ es.byte(di) = 1;
+ _add(di, 26);
+ cx = 3;
+keyloop:
+ es.byte(di) = 0;
+ _add(di, 26);
+ if (--cx)
+ goto keyloop;
+ createpanel();
+ showpanel();
+ showicon();
+ drawfloor();
+ getridofall();
+ dx = 1974;
+ loadintotemp();
+ loadpersonal();
+ loadnews();
+ loadcart();
+ dx = 1870;
+ loadtempcharset();
+ printoutermon();
+ initialmoncols();
+ printlogo();
+ worktoscreen();
+ turnonpower();
+ fadeupyellows();
+ fadeupmonfirst();
+ data.word(kMonadx) = 76;
+ data.word(kMonady) = 141;
+ al = 1;
+ monmessage();
+ cx = 120;
+ hangoncurs();
+ al = 2;
+ monmessage();
+ cx = 60;
+ randomaccess();
+ al = 3;
+ monmessage();
+ cx = 100;
+ hangoncurs();
+ printlogo();
+ scrollmonitor();
+ data.word(kBufferin) = 0;
+ data.word(kBufferout) = 0;
+moreinput:
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ push(di);
+ push(bx);
+ input();
+ bx = pop();
+ di = pop();
+ data.word(kMonadx) = di;
+ data.word(kMonady) = bx;
+ execcommand();
+ _cmp(al, 0);
+ if (flags.z())
+ goto moreinput;
+ getridoftemp();
+ getridoftempcharset();
+ es = data.word(kTextfile1);
+ deallocatemem();
+ es = data.word(kTextfile2);
+ deallocatemem();
+ es = data.word(kTextfile3);
+ deallocatemem();
+ data.byte(kGetback) = 1;
+ al = 26;
+ playchannel1();
+ data.byte(kManisoffscreen) = 0;
+ restoreall();
+ redrawmainscrn();
+ worktoscreenm();
+}
+
+void DreamGenContext::printoutermon() {
+ STACK_CHECK;
+ di = 40;
+ bx = 32;
+ ds = data.word(kTempgraphics);
+ al = 1;
+ ah = 0;
+ showframe();
+ di = 264;
+ bx = 32;
+ ds = data.word(kTempgraphics);
+ al = 2;
+ ah = 0;
+ showframe();
+ di = 40;
+ bx = 12;
+ ds = data.word(kTempgraphics);
+ al = 3;
+ ah = 0;
+ showframe();
+ di = 40;
+ bx = 164;
+ ds = data.word(kTempgraphics);
+ al = 4;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::loadpersonal() {
+ STACK_CHECK;
+ al = data.byte(kLocation);
+ dx = 2052;
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundpersonal;
+ _cmp(al, 42);
+ if (flags.z())
+ goto foundpersonal;
+ dx = 2065;
+ _cmp(al, 2);
+ if (flags.z())
+ goto foundpersonal;
+foundpersonal:
+ openfile();
+ readheader();
+ bx = es.word(di);
+ push(bx);
+ cl = 4;
+ _shr(bx, cl);
+ allocatemem();
+ data.word(kTextfile1) = ax;
+ ds = ax;
+ cx = pop();
+ dx = 0;
+ readfromfile();
+ closefile();
+}
+
+void DreamGenContext::loadnews() {
+ STACK_CHECK;
+ al = data.byte(kNewsitem);
+ dx = 2078;
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundnews;
+ dx = 2091;
+ _cmp(al, 1);
+ if (flags.z())
+ goto foundnews;
+ dx = 2104;
+ _cmp(al, 2);
+ if (flags.z())
+ goto foundnews;
+ dx = 2117;
+foundnews:
+ openfile();
+ readheader();
+ bx = es.word(di);
+ push(bx);
+ cl = 4;
+ _shr(bx, cl);
+ allocatemem();
+ data.word(kTextfile2) = ax;
+ ds = ax;
+ cx = pop();
+ dx = 0;
+ readfromfile();
+ closefile();
+}
+
+void DreamGenContext::loadcart() {
+ STACK_CHECK;
+ lookininterface();
+ dx = 2130;
+ _cmp(al, 0);
+ if (flags.z())
+ goto gotcart;
+ dx = 2143;
+ _cmp(al, 1);
+ if (flags.z())
+ goto gotcart;
+ dx = 2156;
+ _cmp(al, 2);
+ if (flags.z())
+ goto gotcart;
+ dx = 2169;
+ _cmp(al, 3);
+ if (flags.z())
+ goto gotcart;
+ dx = 2182;
+gotcart:
+ openfile();
+ readheader();
+ bx = es.word(di);
+ push(bx);
+ cl = 4;
+ _shr(bx, cl);
+ allocatemem();
+ data.word(kTextfile3) = ax;
+ ds = ax;
+ cx = pop();
+ dx = 0;
+ readfromfile();
+ closefile();
+}
+
+void DreamGenContext::lookininterface() {
+ STACK_CHECK;
+ al = 'I';
+ ah = 'N';
+ cl = 'T';
+ ch = 'F';
+ findsetobject();
+ ah = 1;
+ checkinside();
+ _cmp(cl, (114));
+ if (flags.z())
+ goto emptyinterface;
+ al = es.byte(bx+15);
+ _inc(al);
+ return;
+emptyinterface:
+ al = 0;
+}
+
+void DreamGenContext::turnonpower() {
+ STACK_CHECK;
+ cx = 3;
+powerloop:
+ push(cx);
+ powerlighton();
+ cx = 30;
+ hangon();
+ powerlightoff();
+ cx = 30;
+ hangon();
+ cx = pop();
+ if (--cx)
+ goto powerloop;
+ powerlighton();
+}
+
+void DreamGenContext::randomaccess() {
+ STACK_CHECK;
+accessloop:
+ push(cx);
+ vsync();
+ vsync();
+ randomnum1();
+ _and(al, 15);
+ _cmp(al, 10);
+ if (flags.c())
+ goto off;
+ accesslighton();
+ goto chosenaccess;
+off:
+ accesslightoff();
+chosenaccess:
+ cx = pop();
+ if (--cx)
+ goto accessloop;
+ accesslightoff();
+}
+
+void DreamGenContext::powerlighton() {
+ STACK_CHECK;
+ di = 257+4;
+ bx = 182;
+ ds = data.word(kTempgraphics);
+ al = 6;
+ ah = 0;
+ push(di);
+ push(bx);
+ showframe();
+ bx = pop();
+ di = pop();
+ cl = 12;
+ ch = 8;
+ multidump();
+}
+
+void DreamGenContext::powerlightoff() {
+ STACK_CHECK;
+ di = 257+4;
+ bx = 182;
+ ds = data.word(kTempgraphics);
+ al = 5;
+ ah = 0;
+ push(di);
+ push(bx);
+ showframe();
+ bx = pop();
+ di = pop();
+ cl = 12;
+ ch = 8;
+ multidump();
+}
+
+void DreamGenContext::accesslighton() {
+ STACK_CHECK;
+ di = 74;
+ bx = 182;
+ ds = data.word(kTempgraphics);
+ al = 8;
+ ah = 0;
+ push(di);
+ push(bx);
+ showframe();
+ bx = pop();
+ di = pop();
+ cl = 12;
+ ch = 8;
+ multidump();
+}
+
+void DreamGenContext::accesslightoff() {
+ STACK_CHECK;
+ di = 74;
+ bx = 182;
+ ds = data.word(kTempgraphics);
+ al = 7;
+ ah = 0;
+ push(di);
+ push(bx);
+ showframe();
+ bx = pop();
+ di = pop();
+ cl = 12;
+ ch = 8;
+ multidump();
+}
+
+void DreamGenContext::locklighton() {
+ STACK_CHECK;
+ di = 56;
+ bx = 182;
+ ds = data.word(kTempgraphics);
+ al = 10;
+ ah = 0;
+ push(di);
+ push(bx);
+ showframe();
+ bx = pop();
+ di = pop();
+ cl = 12;
+ ch = 8;
+ multidump();
+}
+
+void DreamGenContext::locklightoff() {
+ STACK_CHECK;
+ di = 56;
+ bx = 182;
+ ds = data.word(kTempgraphics);
+ al = 9;
+ ah = 0;
+ push(di);
+ push(bx);
+ showframe();
+ bx = pop();
+ di = pop();
+ cl = 12;
+ ch = 8;
+ multidump();
+}
+
+void DreamGenContext::input() {
+ STACK_CHECK;
+ es = cs;
+ di = 8045;
+ cx = 64;
+ al = 0;
+ _stosb(cx, true);
+ data.word(kCurpos) = 0;
+ al = '>';
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ ds = data.word(kTempcharset);
+ ah = 0;
+ printchar();
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ cl = 6;
+ ch = 8;
+ multidump();
+ _add(data.word(kMonadx), 6);
+ ax = data.word(kMonadx);
+ data.word(kCurslocx) = ax;
+ ax = data.word(kMonady);
+ data.word(kCurslocy) = ax;
+waitkey:
+ printcurs();
+ vsync();
+ delcurs();
+ readkey();
+ al = data.byte(kCurrentkey);
+ _cmp(al, 0);
+ if (flags.z())
+ goto waitkey;
+ _cmp(al, 13);
+ if (flags.z())
+ return /* (endofinput) */;
+ _cmp(al, 8);
+ if (!flags.z())
+ goto notdel;
+ _cmp(data.word(kCurpos), 0);
+ if (flags.z())
+ goto waitkey;
+ delchar();
+ goto waitkey;
+notdel:
+ _cmp(data.word(kCurpos), 28);
+ if (flags.z())
+ goto waitkey;
+ _cmp(data.byte(kCurrentkey), 32);
+ if (!flags.z())
+ goto notleadingspace;
+ _cmp(data.word(kCurpos), 0);
+ if (flags.z())
+ goto waitkey;
+notleadingspace:
+ makecaps();
+ es = cs;
+ si = data.word(kCurpos);
+ _add(si, si);
+ _add(si, 8045);
+ es.byte(si) = al;
+ _cmp(al, 'Z'+1);
+ if (!flags.c())
+ goto waitkey;
+ push(ax);
+ push(es);
+ push(si);
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ ds = data.word(kMapstore);
+ ax = data.word(kCurpos);
+ _xchg(al, ah);
+ si = ax;
+ cl = 8;
+ ch = 8;
+ multiget();
+ si = pop();
+ es = pop();
+ ax = pop();
+ push(es);
+ push(si);
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ ds = data.word(kTempcharset);
+ ah = 0;
+ printchar();
+ si = pop();
+ es = pop();
+ es.byte(si+1) = cl;
+ ch = 0;
+ _add(data.word(kMonadx), cx);
+ _inc(data.word(kCurpos));
+ _add(data.word(kCurslocx), cx);
+ goto waitkey;
+}
+
+void DreamGenContext::makecaps() {
+ STACK_CHECK;
+ _cmp(al, 'a');
+ if (flags.c())
+ return /* (notupperc) */;
+ _sub(al, 32);
+}
+
+void DreamGenContext::delchar() {
+ STACK_CHECK;
+ _dec(data.word(kCurpos));
+ si = data.word(kCurpos);
+ _add(si, si);
+ es = cs;
+ _add(si, 8045);
+ es.byte(si) = 0;
+ al = es.byte(si+1);
+ ah = 0;
+ _sub(data.word(kMonadx), ax);
+ _sub(data.word(kCurslocx), ax);
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ ds = data.word(kMapstore);
+ ax = data.word(kCurpos);
+ _xchg(al, ah);
+ si = ax;
+ cl = 8;
+ ch = 8;
+ multiput();
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ cl = al;
+ ch = 8;
+ multidump();
+}
+
+void DreamGenContext::execcommand() {
+ STACK_CHECK;
+ es = cs;
+ bx = 2776;
+ ds = cs;
+ si = 8045;
+ al = ds.byte(si);
+ _cmp(al, 0);
+ if (!flags.z())
+ goto notblankinp;
+ scrollmonitor();
+ return;
+notblankinp:
+ cl = 0;
+comloop:
+ push(bx);
+ push(si);
+comloop2:
+ al = ds.byte(si);
+ _add(si, 2);
+ ah = es.byte(bx);
+ _inc(bx);
+ _cmp(ah, 32);
+ if (flags.z())
+ goto foundcom;
+ _cmp(al, ah);
+ if (flags.z())
+ goto comloop2;
+ si = pop();
+ bx = pop();
+ _add(bx, 10);
+ _inc(cl);
+ _cmp(cl, 6);
+ if (!flags.z())
+ goto comloop;
+ neterror();
+ al = 0;
+ return;
+foundcom:
+ si = pop();
+ bx = pop();
+ _cmp(cl, 1);
+ if (flags.z())
+ goto testcom;
+ _cmp(cl, 2);
+ if (flags.z())
+ goto directory;
+ _cmp(cl, 3);
+ if (flags.z())
+ goto accesscom;
+ _cmp(cl, 4);
+ if (flags.z())
+ goto signoncom;
+ _cmp(cl, 5);
+ if (flags.z())
+ goto keyscom;
+ goto quitcom;
+directory:
+ dircom();
+ al = 0;
+ return;
+signoncom:
+ signon();
+ al = 0;
+ return;
+accesscom:
+ read();
+ al = 0;
+ return;
+keyscom:
+ showkeys();
+ al = 0;
+ return;
+testcom:
+ al = 6;
+ monmessage();
+ al = 0;
+ return;
+quitcom:
+ al = 1;
+}
+
+void DreamGenContext::neterror() {
+ STACK_CHECK;
+ al = 5;
+ monmessage();
+ scrollmonitor();
+}
+
+void DreamGenContext::dircom() {
+ STACK_CHECK;
+ cx = 30;
+ randomaccess();
+ parser();
+ _cmp(es.byte(di+1), 0);
+ if (flags.z())
+ goto dirroot;
+ dirfile();
+ return;
+dirroot:
+ data.byte(kLogonum) = 0;
+ ds = cs;
+ si = 2956;
+ _inc(si);
+ es = cs;
+ di = 2970;
+ _inc(di);
+ cx = 12;
+ _movsb(cx, true);
+ monitorlogo();
+ scrollmonitor();
+ al = 9;
+ monmessage();
+ es = data.word(kTextfile1);
+ searchforfiles();
+ es = data.word(kTextfile2);
+ searchforfiles();
+ es = data.word(kTextfile3);
+ searchforfiles();
+ scrollmonitor();
+}
+
+void DreamGenContext::searchforfiles() {
+ STACK_CHECK;
+ bx = (66*2);
+directloop1:
+ al = es.byte(bx);
+ _inc(bx);
+ _cmp(al, '*');
+ if (flags.z())
+ return /* (endofdir) */;
+ _cmp(al, 34);
+ if (!flags.z())
+ goto directloop1;
+ monprint();
+ goto directloop1;
+}
+
+void DreamGenContext::signon() {
+ STACK_CHECK;
+ parser();
+ _inc(di);
+ ds = cs;
+ si = 2836;
+ cx = 4;
+signonloop:
+ push(cx);
+ push(si);
+ push(di);
+ _add(si, 14);
+ cx = 11;
+signonloop2:
+ _lodsb();
+ _cmp(al, 32);
+ if (flags.z())
+ goto foundsign;
+ makecaps();
+ ah = es.byte(di);
+ _inc(di);
+ _cmp(al, ah);
+ if (!flags.z())
+ goto nomatch;
+ if (--cx)
+ goto signonloop2;
+nomatch:
+ di = pop();
+ si = pop();
+ cx = pop();
+ _add(si, 26);
+ if (--cx)
+ goto signonloop;
+ al = 13;
+ monmessage();
+ return;
+foundsign:
+ di = pop();
+ si = pop();
+ cx = pop();
+ bx = si;
+ es = ds;
+ _cmp(es.byte(bx), 0);
+ if (flags.z())
+ goto notyetassigned;
+ al = 17;
+ monmessage();
+ return;
+notyetassigned:
+ push(es);
+ push(bx);
+ scrollmonitor();
+ al = 15;
+ monmessage();
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ push(di);
+ push(bx);
+ input();
+ bx = pop();
+ di = pop();
+ data.word(kMonadx) = di;
+ data.word(kMonady) = bx;
+ bx = pop();
+ es = pop();
+ push(es);
+ push(bx);
+ _add(bx, 2);
+ ds = cs;
+ si = 8045;
+checkpass:
+ _lodsw();
+ ah = es.byte(bx);
+ _inc(bx);
+ _cmp(ah, 32);
+ if (flags.z())
+ goto passpassed;
+ _cmp(al, ah);
+ if (flags.z())
+ goto checkpass;
+ bx = pop();
+ es = pop();
+ scrollmonitor();
+ al = 16;
+ monmessage();
+ return;
+passpassed:
+ al = 14;
+ monmessage();
+ bx = pop();
+ es = pop();
+ push(es);
+ push(bx);
+ _add(bx, 14);
+ monprint();
+ scrollmonitor();
+ bx = pop();
+ es = pop();
+ es.byte(bx) = 1;
+}
+
+void DreamGenContext::showkeys() {
+ STACK_CHECK;
+ cx = 10;
+ randomaccess();
+ scrollmonitor();
+ al = 18;
+ monmessage();
+ es = cs;
+ bx = 2836;
+ cx = 4;
+keysloop:
+ push(cx);
+ push(bx);
+ _cmp(es.byte(bx), 0);
+ if (flags.z())
+ goto notheld;
+ _add(bx, 14);
+ monprint();
+notheld:
+ bx = pop();
+ cx = pop();
+ _add(bx, 26);
+ if (--cx)
+ goto keysloop;
+ scrollmonitor();
+}
+
+void DreamGenContext::read() {
+ STACK_CHECK;
+ cx = 40;
+ randomaccess();
+ parser();
+ _cmp(es.byte(di+1), 0);
+ if (!flags.z())
+ goto okcom;
+ neterror();
+ return;
+okcom:
+ es = cs;
+ di = 2970;
+ ax = data.word(kTextfile1);
+ data.word(kMonsource) = ax;
+ ds = ax;
+ si = (66*2);
+ searchforstring();
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundfile2;
+ ax = data.word(kTextfile2);
+ data.word(kMonsource) = ax;
+ ds = ax;
+ si = (66*2);
+ searchforstring();
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundfile2;
+ ax = data.word(kTextfile3);
+ data.word(kMonsource) = ax;
+ ds = ax;
+ si = (66*2);
+ searchforstring();
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundfile2;
+ al = 7;
+ monmessage();
+ return;
+foundfile2:
+ getkeyandlogo();
+ _cmp(al, 0);
+ if (flags.z())
+ goto keyok1;
+ return;
+keyok1:
+ es = cs;
+ di = 2942;
+ ds = data.word(kMonsource);
+ searchforstring();
+ _cmp(al, 0);
+ if (flags.z())
+ goto findtopictext;
+ al = data.byte(kOldlogonum);
+ data.byte(kLogonum) = al;
+ al = 11;
+ monmessage();
+ return;
+findtopictext:
+ _inc(bx);
+ push(es);
+ push(bx);
+ monitorlogo();
+ scrollmonitor();
+ bx = pop();
+ es = pop();
+moretopic:
+ monprint();
+ al = es.byte(bx);
+ _cmp(al, 34);
+ if (flags.z())
+ goto endoftopic;
+ _cmp(al, '=');
+ if (flags.z())
+ goto endoftopic;
+ _cmp(al, '*');
+ if (flags.z())
+ goto endoftopic;
+ push(es);
+ push(bx);
+ processtrigger();
+ cx = 24;
+ randomaccess();
+ bx = pop();
+ es = pop();
+ goto moretopic;
+endoftopic:
+ scrollmonitor();
+}
+
+void DreamGenContext::dirfile() {
+ STACK_CHECK;
+ al = 34;
+ es.byte(di) = al;
+ push(es);
+ push(di);
+ ds = data.word(kTextfile1);
+ si = (66*2);
+ searchforstring();
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundfile;
+ di = pop();
+ es = pop();
+ push(es);
+ push(di);
+ ds = data.word(kTextfile2);
+ si = (66*2);
+ searchforstring();
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundfile;
+ di = pop();
+ es = pop();
+ push(es);
+ push(di);
+ ds = data.word(kTextfile3);
+ si = (66*2);
+ searchforstring();
+ _cmp(al, 0);
+ if (flags.z())
+ goto foundfile;
+ di = pop();
+ es = pop();
+ al = 7;
+ monmessage();
+ return;
+foundfile:
+ ax = pop();
+ ax = pop();
+ getkeyandlogo();
+ _cmp(al, 0);
+ if (flags.z())
+ goto keyok2;
+ return;
+keyok2:
+ push(es);
+ push(bx);
+ ds = cs;
+ si = 2942+1;
+ es = cs;
+ di = 2970+1;
+ cx = 12;
+ _movsb(cx, true);
+ monitorlogo();
+ scrollmonitor();
+ al = 10;
+ monmessage();
+ bx = pop();
+ es = pop();
+directloop2:
+ al = es.byte(bx);
+ _inc(bx);
+ _cmp(al, 34);
+ if (flags.z())
+ goto endofdir2;
+ _cmp(al, '*');
+ if (flags.z())
+ goto endofdir2;
+ _cmp(al, '=');
+ if (!flags.z())
+ goto directloop2;
+ monprint();
+ goto directloop2;
+endofdir2:
+ scrollmonitor();
+}
+
+void DreamGenContext::getkeyandlogo() {
+ STACK_CHECK;
+ _inc(bx);
+ al = es.byte(bx);
+ _sub(al, 48);
+ data.byte(kNewlogonum) = al;
+ _add(bx, 2);
+ al = es.byte(bx);
+ _sub(al, 48);
+ data.byte(kKeynum) = al;
+ _inc(bx);
+ push(es);
+ push(bx);
+ al = data.byte(kKeynum);
+ ah = 0;
+ cx = 26;
+ _mul(cx);
+ es = cs;
+ bx = 2836;
+ _add(bx, ax);
+ al = es.byte(bx);
+ _cmp(al, 1);
+ if (flags.z())
+ goto keyok;
+ push(bx);
+ push(es);
+ al = 12;
+ monmessage();
+ es = pop();
+ bx = pop();
+ _add(bx, 14);
+ monprint();
+ scrollmonitor();
+ bx = pop();
+ es = pop();
+ al = 1;
+ return;
+keyok:
+ bx = pop();
+ es = pop();
+ al = data.byte(kNewlogonum);
+ data.byte(kLogonum) = al;
+ al = 0;
+}
+
+void DreamGenContext::searchforstring() {
+ STACK_CHECK;
+ dl = es.byte(di);
+ cx = di;
+restartlook:
+ di = cx;
+ bx = si;
+ dh = 0;
+keeplooking:
+ _lodsb();
+ makecaps();
+ _cmp(al, '*');
+ if (flags.z())
+ goto notfound;
+ _cmp(dl, '=');
+ if (!flags.z())
+ goto nofindingtopic;
+ _cmp(al, 34);
+ if (flags.z())
+ goto notfound;
+nofindingtopic:
+ ah = es.byte(di);
+ _cmp(al, dl);
+ if (!flags.z())
+ goto notbracket;
+ _inc(dh);
+ _cmp(dh, 2);
+ if (flags.z())
+ goto complete;
+notbracket:
+ _cmp(al, ah);
+ if (!flags.z())
+ goto restartlook;
+ _inc(di);
+ goto keeplooking;
+complete:
+ es = ds;
+ al = 0;
+ bx = si;
+ return;
+notfound:
+ al = 1;
+}
+
+void DreamGenContext::parser() {
+ STACK_CHECK;
+ es = cs;
+ di = 2942;
+ cx = 13;
+ al = 0;
+ _stosb(cx, true);
+ di = 2942;
+ al = '=';
+ _stosb();
+ ds = cs;
+ si = 8045;
+notspace1:
+ _lodsw();
+ _cmp(al, 32);
+ if (flags.z())
+ goto stillspace1;
+ _cmp(al, 0);
+ if (!flags.z())
+ goto notspace1;
+ goto finishpars;
+stillspace1:
+ _lodsw();
+ _cmp(al, 32);
+ if (flags.z())
+ goto stillspace1;
+copyin1:
+ _stosb();
+ _lodsw();
+ _cmp(al, 0);
+ if (flags.z())
+ goto finishpars;
+ _cmp(al, 32);
+ if (!flags.z())
+ goto copyin1;
+finishpars:
+ di = 2942;
+}
+
+void DreamGenContext::scrollmonitor() {
+ STACK_CHECK;
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ push(di);
+ push(si);
+ push(es);
+ push(ds);
+ printlogo();
+ di = data.word(kMonadx);
+ bx = data.word(kMonady);
+ printundermon();
+ ax = data.word(kMonady);
+ worktoscreen();
+ al = 25;
+ playchannel1();
+ ds = pop();
+ es = pop();
+ si = pop();
+ di = pop();
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+}
+
+void DreamGenContext::lockmon() {
+ STACK_CHECK;
+ _cmp(data.byte(kLasthardkey), 57);
+ if (!flags.z())
+ return /* (notlock) */;
+ locklighton();
+lockloop:
+ _cmp(data.byte(kLasthardkey), 57);
+ if (flags.z())
+ goto lockloop;
+ locklightoff();
+}
+
+void DreamGenContext::monitorlogo() {
+ STACK_CHECK;
+ al = data.byte(kLogonum);
+ _cmp(al, data.byte(kOldlogonum));
+ if (flags.z())
+ goto notnewlogo;
+ data.byte(kOldlogonum) = al;
+ printlogo();
+ printundermon();
+ worktoscreen();
+ printlogo();
+ printlogo();
+ al = 26;
+ playchannel1();
+ cx = 20;
+ randomaccess();
+ return;
+notnewlogo:
+ printlogo();
+}
+
+void DreamGenContext::printlogo() {
+ STACK_CHECK;
+ di = 56;
+ bx = 32;
+ ds = data.word(kTempgraphics);
+ al = 0;
+ ah = 0;
+ showframe();
+ showcurrentfile();
+}
+
+void DreamGenContext::showcurrentfile() {
+ STACK_CHECK;
+ di = 178;
+ bx = 37;
+ si = 2970+1;
+curfileloop:
+ al = cs.byte(si);
+ _cmp(al, 0);
+ if (flags.z())
+ return /* (finishfile) */;
+ _inc(si);
+ push(si);
+ modifychar();
+ ds = data.word(kTempcharset);
+ ah = 0;
+ printchar();
+ si = pop();
+ goto curfileloop;
+}
+
+void DreamGenContext::monmessage() {
+ STACK_CHECK;
+ es = data.word(kTextfile1);
+ bx = (66*2);
+ cl = al;
+ ch = 0;
+monmessageloop:
+ al = es.byte(bx);
+ _inc(bx);
+ _cmp(al, '+');
+ if (!flags.z())
+ goto monmessageloop;
+ if (--cx)
+ goto monmessageloop;
+ monprint();
+}
+
+void DreamGenContext::processtrigger() {
+ STACK_CHECK;
+ _cmp(data.byte(kLasttrigger), '1');
+ if (!flags.z())
+ goto notfirsttrigger;
+ al = 8;
+ setlocation();
+ al = 45;
+ triggermessage();
+ return;
+notfirsttrigger:
+ _cmp(data.byte(kLasttrigger), '2');
+ if (!flags.z())
+ goto notsecondtrigger;
+ al = 9;
+ setlocation();
+ al = 55;
+ triggermessage();
+ return;
+notsecondtrigger:
+ _cmp(data.byte(kLasttrigger), '3');
+ if (!flags.z())
+ return /* (notthirdtrigger) */;
+ al = 2;
+ setlocation();
+ al = 59;
+ triggermessage();
+}
+
+void DreamGenContext::triggermessage() {
+ STACK_CHECK;
+ push(ax);
+ di = 174;
+ bx = 153;
+ cl = 200;
+ ch = 63;
+ ds = data.word(kMapstore);
+ si = 0;
+ multiget();
+ ax = pop();
+ findpuztext();
+ di = 174;
+ bx = 156;
+ dl = 141;
+ ah = 16;
+ printdirect();
+ cx = 140;
+ hangon();
+ worktoscreen();
+ cx = 340;
+ hangon();
+ di = 174;
+ bx = 153;
+ cl = 200;
+ ch = 63;
+ ds = data.word(kMapstore);
+ si = 0;
+ multiput();
+ worktoscreen();
+ data.byte(kLasttrigger) = 0;
+}
+
+void DreamGenContext::printcurs() {
+ STACK_CHECK;
+ push(si);
+ push(di);
+ push(ds);
+ push(dx);
+ push(bx);
+ push(es);
+ di = data.word(kCurslocx);
+ bx = data.word(kCurslocy);
+ cl = 6;
+ ch = 8;
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(bx, 3);
+ ch = 11;
+_tmp1:
+ ds = data.word(kBuffers);
+ si = (0);
+ push(di);
+ push(bx);
+ multiget();
+ bx = pop();
+ di = pop();
+ push(bx);
+ push(di);
+ _inc(data.word(kMaintimer));
+ ax = data.word(kMaintimer);
+ _and(al, 16);
+ if (!flags.z())
+ goto flashcurs;
+ al = '/';
+ _sub(al, 32);
+ ah = 0;
+ ds = data.word(kTempcharset);
+ showframe();
+flashcurs:
+ di = pop();
+ bx = pop();
+ _sub(di, 6);
+ cl = 12;
+ ch = 8;
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp2;
+ ch = 11;
+_tmp2:
+ multidump();
+ es = pop();
+ bx = pop();
+ dx = pop();
+ ds = pop();
+ di = pop();
+ si = pop();
+}
+
+void DreamGenContext::delcurs() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ push(di);
+ push(ds);
+ push(dx);
+ push(si);
+ di = data.word(kCurslocx);
+ bx = data.word(kCurslocy);
+ cl = 6;
+ ch = 8;
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(bx, 3);
+ ch = 11;
+_tmp1:
+ push(di);
+ push(bx);
+ push(cx);
+ ds = data.word(kBuffers);
+ si = (0);
+ multiput();
+ cx = pop();
+ bx = pop();
+ di = pop();
+ multidump();
+ si = pop();
+ dx = pop();
+ ds = pop();
+ di = pop();
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::useobject() {
+ STACK_CHECK;
+ data.byte(kWithobject) = 255;
+ _cmp(data.byte(kCommandtype), 229);
+ if (flags.z())
+ goto alreadyuse;
+ data.byte(kCommandtype) = 229;
+ bl = data.byte(kCommand);
+ bh = data.byte(kObjecttype);
+ al = 51;
+ commandwithob();
+alreadyuse:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nouse) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto douse;
+ return;
+douse:
+ useroutine();
+}
+
+void DreamGenContext::useroutine() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 50);
+ if (flags.c())
+ goto nodream7;
+ _cmp(data.byte(kPointerpower), 0);
+ if (!flags.z())
+ goto powerok;
+ return;
+powerok:
+ data.byte(kPointerpower) = 0;
+nodream7:
+ getanyad();
+ dx = data;
+ ds = dx;
+ si = 2984;
+checkuselist:
+ push(si);
+ _lodsb();
+ _sub(al, 'A');
+ _cmp(al, es.byte(bx+12));
+ if (!flags.z())
+ goto failed;
+ _lodsb();
+ _sub(al, 'A');
+ _cmp(al, es.byte(bx+13));
+ if (!flags.z())
+ goto failed;
+ _lodsb();
+ _sub(al, 'A');
+ _cmp(al, es.byte(bx+14));
+ if (!flags.z())
+ goto failed;
+ _lodsb();
+ _sub(al, 'A');
+ _cmp(al, es.byte(bx+15));
+ if (!flags.z())
+ goto failed;
+ _lodsw();
+ si = pop();
+ __dispatch_call(ax);
+ return;
+failed:
+ si = pop();
+ _add(si, 6);
+ _cmp(ds.byte(si), 140);
+ if (!flags.z())
+ goto checkuselist;
+ delpointer();
+ getobtextstart();
+ findnextcolon();
+ _cmp(al, 0);
+ if (flags.z())
+ goto cantuse2;
+ findnextcolon();
+ _cmp(al, 0);
+ if (flags.z())
+ goto cantuse2;
+ al = es.byte(si);
+ _cmp(al, 0);
+ if (flags.z())
+ goto cantuse2;
+ usetext();
+ cx = 400;
+ hangonp();
+ putbackobstuff();
+ return;
+cantuse2:
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ obicons();
+ di = 33;
+ bx = 100;
+ al = 63;
+ dl = 241;
+ printmessage();
+ worktoscreenm();
+ cx = 50;
+ hangonp();
+ putbackobstuff();
+ data.byte(kCommandtype) = 255;
+}
+
+void DreamGenContext::wheelsound() {
+ STACK_CHECK;
+ al = 17;
+ playchannel1();
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::runtap() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto tapwith;
+ withwhat();
+ return;
+tapwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto fillcupfromtap;
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'F';
+ compare();
+ if (flags.z())
+ goto cupfromtapfull;
+ cx = 300;
+ al = 56;
+ showpuztext();
+ putbackobstuff();
+ return;
+fillcupfromtap:
+ al = data.byte(kWithobject);
+ getexad();
+ es.byte(bx+15) = 'F'-'A';
+ al = 8;
+ playchannel1();
+ cx = 300;
+ al = 57;
+ showpuztext();
+ putbackobstuff();
+ return;
+cupfromtapfull:
+ cx = 300;
+ al = 58;
+ showpuztext();
+ putbackobstuff();
+}
+
+void DreamGenContext::playguitar() {
+ STACK_CHECK;
+ al = 14;
+ playchannel1();
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::hotelcontrol() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 21);
+ if (!flags.z())
+ goto notrightcont;
+ _cmp(data.byte(kMapx), 33);
+ if (!flags.z())
+ goto notrightcont;
+ showfirstuse();
+ putbackobstuff();
+ return;
+notrightcont:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::hotelbell() {
+ STACK_CHECK;
+ al = 12;
+ playchannel1();
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::opentomb() {
+ STACK_CHECK;
+ _inc(data.byte(kProgresspoints));
+ showfirstuse();
+ data.word(kWatchingtime) = 35*2;
+ data.word(kReeltowatch) = 1;
+ data.word(kEndwatchreel) = 33;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usetrainer() {
+ STACK_CHECK;
+ getanyad();
+ _cmp(es.byte(bx+2), 4);
+ if (!flags.z())
+ goto notheldtrainer;
+ _inc(data.byte(kProgresspoints));
+ makeworn();
+ showseconduse();
+ putbackobstuff();
+ return;
+notheldtrainer:
+ nothelderror();
+}
+
+void DreamGenContext::nothelderror() {
+ STACK_CHECK;
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ obicons();
+ di = 64;
+ bx = 100;
+ al = 63;
+ ah = 1;
+ dl = 201;
+ printmessage2();
+ worktoscreenm();
+ cx = 50;
+ hangonp();
+ putbackobstuff();
+}
+
+void DreamGenContext::usepipe() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto pipewith;
+ withwhat();
+ return;
+pipewith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto fillcup;
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'F';
+ compare();
+ if (flags.z())
+ goto alreadyfull;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+fillcup:
+ cx = 300;
+ al = 36;
+ showpuztext();
+ putbackobstuff();
+ al = data.byte(kWithobject);
+ getexad();
+ es.byte(bx+15) = 'F'-'A';
+ return;
+alreadyfull:
+ cx = 300;
+ al = 35;
+ showpuztext();
+ putbackobstuff();
+}
+
+void DreamGenContext::usefullcart() {
+ STACK_CHECK;
+ _inc(data.byte(kProgresspoints));
+ al = 2;
+ ah = data.byte(kRoomnum);
+ _add(ah, 6);
+ turnanypathon();
+ data.byte(kManspath) = 4;
+ data.byte(kFacing) = 4;
+ data.byte(kTurntoface) = 4;
+ data.byte(kFinaldest) = 4;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ showfirstuse();
+ data.word(kWatchingtime) = 72*2;
+ data.word(kReeltowatch) = 58;
+ data.word(kEndwatchreel) = 142;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useplinth() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto plinthwith;
+ withwhat();
+ return;
+plinthwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'D';
+ ch = 'K';
+ dl = 'E';
+ dh = 'Y';
+ compare();
+ if (flags.z())
+ goto isrightkey;
+ showfirstuse();
+ putbackobstuff();
+ return;
+isrightkey:
+ _inc(data.byte(kProgresspoints));
+ showseconduse();
+ data.word(kWatchingtime) = 220;
+ data.word(kReeltowatch) = 0;
+ data.word(kEndwatchreel) = 104;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ al = data.byte(kRoomafterdream);
+ data.byte(kNewlocation) = al;
+}
+
+void DreamGenContext::chewy() {
+ STACK_CHECK;
+ showfirstuse();
+ getanyad();
+ es.byte(bx+2) = 255;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useladder() {
+ STACK_CHECK;
+ showfirstuse();
+ _sub(data.byte(kMapx), 11);
+ findroominloc();
+ data.byte(kFacing) = 6;
+ data.byte(kTurntoface) = 6;
+ data.byte(kManspath) = 0;
+ data.byte(kDestination) = 0;
+ data.byte(kFinaldest) = 0;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useladderb() {
+ STACK_CHECK;
+ showfirstuse();
+ _add(data.byte(kMapx), 11);
+ findroominloc();
+ data.byte(kFacing) = 2;
+ data.byte(kTurntoface) = 2;
+ data.byte(kManspath) = 1;
+ data.byte(kDestination) = 1;
+ data.byte(kFinaldest) = 1;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::slabdoora() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kReeltowatch) = 13;
+ _cmp(data.byte(kDreamnumber), 3);
+ if (!flags.z())
+ goto slabawrong;
+ _inc(data.byte(kProgresspoints));
+ data.word(kWatchingtime) = 60;
+ data.word(kEndwatchreel) = 42;
+ data.byte(kNewlocation) = 47;
+ return;
+slabawrong:
+ data.word(kWatchingtime) = 40;
+ data.word(kEndwatchreel) = 34;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+}
+
+void DreamGenContext::slabdoorb() {
+ STACK_CHECK;
+ _cmp(data.byte(kDreamnumber), 1);
+ if (!flags.z())
+ goto slabbwrong;
+ al = 'S';
+ ah = 'H';
+ cl = 'L';
+ ch = 'D';
+ isryanholding();
+ if (!flags.z())
+ goto gotcrystal;
+ al = 44;
+ cx = 200;
+ showpuztext();
+ putbackobstuff();
+ return;
+gotcrystal:
+ showfirstuse();
+ _inc(data.byte(kProgresspoints));
+ data.byte(kGetback) = 1;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kReeltowatch) = 44;
+ data.word(kWatchingtime) = 60;
+ data.word(kEndwatchreel) = 71;
+ data.byte(kNewlocation) = 47;
+ return;
+slabbwrong:
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kReeltowatch) = 44;
+ data.word(kWatchingtime) = 40;
+ data.word(kEndwatchreel) = 63;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+}
+
+void DreamGenContext::slabdoord() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kReeltowatch) = 75;
+ _cmp(data.byte(kDreamnumber), 0);
+ if (!flags.z())
+ goto slabcwrong;
+ _inc(data.byte(kProgresspoints));
+ data.word(kWatchingtime) = 60;
+ data.word(kEndwatchreel) = 102;
+ data.byte(kNewlocation) = 47;
+ return;
+slabcwrong:
+ data.word(kWatchingtime) = 40;
+ data.word(kEndwatchreel) = 94;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+}
+
+void DreamGenContext::slabdoorc() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kReeltowatch) = 108;
+ _cmp(data.byte(kDreamnumber), 4);
+ if (!flags.z())
+ goto slabdwrong;
+ _inc(data.byte(kProgresspoints));
+ data.word(kWatchingtime) = 60;
+ data.word(kEndwatchreel) = 135;
+ data.byte(kNewlocation) = 47;
+ return;
+slabdwrong:
+ data.word(kWatchingtime) = 40;
+ data.word(kEndwatchreel) = 127;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+}
+
+void DreamGenContext::slabdoore() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kReeltowatch) = 141;
+ _cmp(data.byte(kDreamnumber), 5);
+ if (!flags.z())
+ goto slabewrong;
+ _inc(data.byte(kProgresspoints));
+ data.word(kWatchingtime) = 60;
+ data.word(kEndwatchreel) = 168;
+ data.byte(kNewlocation) = 47;
+ return;
+slabewrong:
+ data.word(kWatchingtime) = 40;
+ data.word(kEndwatchreel) = 160;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+}
+
+void DreamGenContext::slabdoorf() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kReeltowatch) = 171;
+ _cmp(data.byte(kDreamnumber), 2);
+ if (!flags.z())
+ goto slabfwrong;
+ _inc(data.byte(kProgresspoints));
+ data.word(kWatchingtime) = 60;
+ data.word(kEndwatchreel) = 197;
+ data.byte(kNewlocation) = 47;
+ return;
+slabfwrong:
+ data.word(kWatchingtime) = 40;
+ data.word(kEndwatchreel) = 189;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+}
+
+void DreamGenContext::useslab() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto slabwith;
+ withwhat();
+ return;
+slabwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'J';
+ ch = 'E';
+ dl = 'W';
+ dh = 'L';
+ compare();
+ if (flags.z())
+ goto nextslab;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+nextslab:
+ al = data.byte(kWithobject);
+ getexad();
+ es.byte(bx+2) = 0;
+ al = data.byte(kCommand);
+ push(ax);
+ removesetobject();
+ ax = pop();
+ _inc(al);
+ push(ax);
+ placesetobject();
+ ax = pop();
+ _cmp(al, 54);
+ if (!flags.z())
+ goto notlastslab;
+ al = 0;
+ turnpathon();
+ data.word(kWatchingtime) = 22;
+ data.word(kReeltowatch) = 35;
+ data.word(kEndwatchreel) = 48;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+notlastslab:
+ _inc(data.byte(kProgresspoints));
+ showfirstuse();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usecart() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto cartwith;
+ withwhat();
+ return;
+cartwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'R';
+ ch = 'O';
+ dl = 'C';
+ dh = 'K';
+ compare();
+ if (flags.z())
+ goto nextcart;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+nextcart:
+ al = data.byte(kWithobject);
+ getexad();
+ es.byte(bx+2) = 0;
+ al = data.byte(kCommand);
+ push(ax);
+ removesetobject();
+ ax = pop();
+ _inc(al);
+ placesetobject();
+ _inc(data.byte(kProgresspoints));
+ al = 17;
+ playchannel1();
+ showfirstuse();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useclearbox() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto clearboxwith;
+ withwhat();
+ return;
+clearboxwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'R';
+ ch = 'A';
+ dl = 'I';
+ dh = 'L';
+ compare();
+ if (flags.z())
+ goto openbox;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+openbox:
+ _inc(data.byte(kProgresspoints));
+ showfirstuse();
+ data.word(kWatchingtime) = 80;
+ data.word(kReeltowatch) = 67;
+ data.word(kEndwatchreel) = 105;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usecoveredbox() {
+ STACK_CHECK;
+ _inc(data.byte(kProgresspoints));
+ showfirstuse();
+ data.word(kWatchingtime) = 50;
+ data.word(kReeltowatch) = 41;
+ data.word(kEndwatchreel) = 66;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::userailing() {
+ STACK_CHECK;
+ showfirstuse();
+ data.word(kWatchingtime) = 80;
+ data.word(kReeltowatch) = 0;
+ data.word(kEndwatchreel) = 30;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ data.byte(kMandead) = 4;
+}
+
+void DreamGenContext::useopenbox() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto openboxwith;
+ withwhat();
+ return;
+openboxwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'F';
+ compare();
+ if (flags.z())
+ goto destoryopenbox;
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'P';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto openboxwrong;
+ showfirstuse();
+ return;
+destoryopenbox:
+ _inc(data.byte(kProgresspoints));
+ cx = 300;
+ al = 37;
+ showpuztext();
+ al = data.byte(kWithobject);
+ getexad();
+ es.byte(bx+15) = 'E'-'A';
+ data.word(kWatchingtime) = 140;
+ data.word(kReeltowatch) = 105;
+ data.word(kEndwatchreel) = 181;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ al = 4;
+ turnpathon();
+ data.byte(kGetback) = 1;
+ return;
+openboxwrong:
+ cx = 300;
+ al = 38;
+ showpuztext();
+ putbackobstuff();
+}
+
+void DreamGenContext::wearwatch() {
+ STACK_CHECK;
+ _cmp(data.byte(kWatchon), 1);
+ if (flags.z())
+ goto wearingwatch;
+ showfirstuse();
+ data.byte(kWatchon) = 1;
+ data.byte(kGetback) = 1;
+ getanyad();
+ makeworn();
+ return;
+wearingwatch:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::wearshades() {
+ STACK_CHECK;
+ _cmp(data.byte(kShadeson), 1);
+ if (flags.z())
+ goto wearingshades;
+ data.byte(kShadeson) = 1;
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ getanyad();
+ makeworn();
+ return;
+wearingshades:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::sitdowninbar() {
+ STACK_CHECK;
+ _cmp(data.byte(kWatchmode), -1);
+ if (!flags.z())
+ goto satdown;
+ showfirstuse();
+ data.word(kWatchingtime) = 50;
+ data.word(kReeltowatch) = 55;
+ data.word(kEndwatchreel) = 71;
+ data.word(kReeltohold) = 73;
+ data.word(kEndofholdreel) = 83;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ return;
+satdown:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::usechurchhole() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kGetback) = 1;
+ data.word(kWatchingtime) = 28;
+ data.word(kReeltowatch) = 13;
+ data.word(kEndwatchreel) = 26;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+}
+
+void DreamGenContext::usehole() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto holewith;
+ withwhat();
+ return;
+holewith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'H';
+ ch = 'N';
+ dl = 'D';
+ dh = 'A';
+ compare();
+ if (flags.z())
+ goto righthand;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+righthand:
+ showfirstuse();
+ al = 86;
+ removesetobject();
+ al = data.byte(kWithobject);
+ getexad();
+ es.byte(bx+2) = 255;
+ data.byte(kCanmovealtar) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usealtar() {
+ STACK_CHECK;
+ al = 'C';
+ ah = 'N';
+ cl = 'D';
+ ch = 'A';
+ findexobject();
+ _cmp(al, (114));
+ if (flags.z())
+ goto thingsonaltar;
+ al = 'C';
+ ah = 'N';
+ cl = 'D';
+ ch = 'B';
+ findexobject();
+ _cmp(al, (114));
+ if (flags.z())
+ goto thingsonaltar;
+ _cmp(data.byte(kCanmovealtar), 1);
+ if (flags.z())
+ goto movealtar;
+ cx = 300;
+ al = 23;
+ showpuztext();
+ data.byte(kGetback) = 1;
+ return;
+movealtar:
+ _inc(data.byte(kProgresspoints));
+ showseconduse();
+ data.word(kWatchingtime) = 160;
+ data.word(kReeltowatch) = 81;
+ data.word(kEndwatchreel) = 174;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ al = 47;
+ bl = 52;
+ bh = 76;
+ cx = 32;
+ dx = 98;
+ setuptimeduse();
+ data.byte(kGetback) = 1;
+ return;
+thingsonaltar:
+ showfirstuse();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::opentvdoor() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto tvdoorwith;
+ withwhat();
+ return;
+tvdoorwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'U';
+ ch = 'L';
+ dl = 'O';
+ dh = 'K';
+ compare();
+ if (flags.z())
+ goto keyontv;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+keyontv:
+ showfirstuse();
+ data.byte(kLockstatus) = 0;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usedryer() {
+ STACK_CHECK;
+ al = 12;
+ playchannel1();
+ showfirstuse();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::openlouis() {
+ STACK_CHECK;
+ al = 5;
+ ah = 2;
+ cl = 3;
+ ch = 8;
+ entercode();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::nextcolon() {
+ STACK_CHECK;
+lookcolon:
+ al = es.byte(si);
+ _inc(si);
+ _cmp(al, ':');
+ if (!flags.z())
+ goto lookcolon;
+}
+
+void DreamGenContext::openyourneighbour() {
+ STACK_CHECK;
+ al = 255;
+ ah = 255;
+ cl = 255;
+ ch = 255;
+ entercode();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usewindow() {
+ STACK_CHECK;
+ _cmp(data.byte(kManspath), 6);
+ if (!flags.z())
+ goto notonbalc;
+ _inc(data.byte(kProgresspoints));
+ showfirstuse();
+ data.byte(kNewlocation) = 29;
+ data.byte(kGetback) = 1;
+ return;
+notonbalc:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::usebalcony() {
+ STACK_CHECK;
+ showfirstuse();
+ al = 6;
+ turnpathon();
+ al = 0;
+ turnpathoff();
+ al = 1;
+ turnpathoff();
+ al = 2;
+ turnpathoff();
+ al = 3;
+ turnpathoff();
+ al = 4;
+ turnpathoff();
+ al = 5;
+ turnpathoff();
+ _inc(data.byte(kProgresspoints));
+ data.byte(kManspath) = 6;
+ data.byte(kDestination) = 6;
+ data.byte(kFinaldest) = 6;
+ findxyfrompath();
+ switchryanoff();
+ data.byte(kResetmanxy) = 1;
+ data.word(kWatchingtime) = 30*2;
+ data.word(kReeltowatch) = 183;
+ data.word(kEndwatchreel) = 212;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::openryan() {
+ STACK_CHECK;
+ al = 5;
+ ah = 1;
+ cl = 0;
+ ch = 6;
+ entercode();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::openpoolboss() {
+ STACK_CHECK;
+ al = 5;
+ ah = 2;
+ cl = 2;
+ ch = 2;
+ entercode();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::openeden() {
+ STACK_CHECK;
+ al = 2;
+ ah = 8;
+ cl = 6;
+ ch = 5;
+ entercode();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::opensarters() {
+ STACK_CHECK;
+ al = 7;
+ ah = 8;
+ cl = 3;
+ ch = 3;
+ entercode();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::isitright() {
+ STACK_CHECK;
+ bx = data;
+ es = bx;
+ bx = 8573;
+ _cmp(es.byte(bx+0), al);
+ if (!flags.z())
+ return /* (notright) */;
+ _cmp(es.byte(bx+1), ah);
+ if (!flags.z())
+ return /* (notright) */;
+ _cmp(es.byte(bx+2), cl);
+ if (!flags.z())
+ return /* (notright) */;
+ _cmp(es.byte(bx+3), ch);
+}
+
+void DreamGenContext::drawitall() {
+ STACK_CHECK;
+ createpanel();
+ drawfloor();
+ printsprites();
+ showicon();
+}
+
+void DreamGenContext::openhoteldoor() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto hoteldoorwith;
+ withwhat();
+ return;
+hoteldoorwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'K';
+ ch = 'E';
+ dl = 'Y';
+ dh = 'A';
+ compare();
+ if (flags.z())
+ goto keyonhotel1;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+keyonhotel1:
+ al = 16;
+ playchannel1();
+ showfirstuse();
+ data.byte(kLockstatus) = 0;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::openhoteldoor2() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto hoteldoorwith2;
+ withwhat();
+ return;
+hoteldoorwith2:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'K';
+ ch = 'E';
+ dl = 'Y';
+ dh = 'A';
+ compare();
+ if (flags.z())
+ goto keyonhotel2;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+keyonhotel2:
+ al = 16;
+ playchannel1();
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::grafittidoor() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto grafwith;
+ withwhat();
+ return;
+grafwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'A';
+ ch = 'P';
+ dl = 'E';
+ dh = 'N';
+ compare();
+ if (flags.z())
+ goto dograf;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+dograf:
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::trapdoor() {
+ STACK_CHECK;
+ _inc(data.byte(kProgresspoints));
+ showfirstuse();
+ switchryanoff();
+ data.word(kWatchingtime) = 20*2;
+ data.word(kReeltowatch) = 181;
+ data.word(kEndwatchreel) = 197;
+ data.byte(kNewlocation) = 26;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::callhotellift() {
+ STACK_CHECK;
+ al = 12;
+ playchannel1();
+ showfirstuse();
+ data.byte(kCounttoopen) = 8;
+ data.byte(kGetback) = 1;
+ data.byte(kDestination) = 5;
+ data.byte(kFinaldest) = 5;
+ autosetwalk();
+ al = 4;
+ turnpathon();
+}
+
+void DreamGenContext::calledenslift() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kCounttoopen) = 8;
+ data.byte(kGetback) = 1;
+ al = 2;
+ turnpathon();
+}
+
+void DreamGenContext::calledensdlift() {
+ STACK_CHECK;
+ _cmp(data.byte(kLiftflag), 1);
+ if (flags.z())
+ goto edensdhere;
+ showfirstuse();
+ data.byte(kCounttoopen) = 8;
+ data.byte(kGetback) = 1;
+ al = 2;
+ turnpathon();
+ return;
+edensdhere:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::usepoolreader() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto poolwith;
+ withwhat();
+ return;
+poolwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'M';
+ ch = 'E';
+ dl = 'M';
+ dh = 'B';
+ compare();
+ if (flags.z())
+ goto openpool;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+openpool:
+ _cmp(data.byte(kTalkedtoattendant), 1);
+ if (flags.z())
+ goto canopenpool;
+ showseconduse();
+ putbackobstuff();
+ return;
+canopenpool:
+ al = 17;
+ playchannel1();
+ showfirstuse();
+ data.byte(kCounttoopen) = 6;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::uselighter() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gotlighterwith;
+ withwhat();
+ return;
+gotlighterwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'S';
+ ch = 'M';
+ dl = 'K';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto cigarette;
+ showfirstuse();
+ putbackobstuff();
+ return;
+cigarette:
+ cx = 300;
+ al = 9;
+ showpuztext();
+ al = data.byte(kWithobject);
+ getexad();
+ es.byte(bx+2) = 255;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::showseconduse() {
+ STACK_CHECK;
+ getobtextstart();
+ nextcolon();
+ nextcolon();
+ nextcolon();
+ usetext();
+ cx = 400;
+ hangonp();
+}
+
+void DreamGenContext::usecardreader1() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gotreader1with;
+ withwhat();
+ return;
+gotreader1with:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'S';
+ dl = 'H';
+ dh = 'R';
+ compare();
+ if (flags.z())
+ goto correctcard;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+correctcard:
+ _cmp(data.byte(kTalkedtosparky), 0);
+ if (flags.z())
+ goto notyet;
+ _cmp(data.word(kCard1money), 0);
+ if (flags.z())
+ goto getscash;
+ cx = 300;
+ al = 17;
+ showpuztext();
+ putbackobstuff();
+ return;
+getscash:
+ al = 16;
+ playchannel1();
+ cx = 300;
+ al = 18;
+ showpuztext();
+ _inc(data.byte(kProgresspoints));
+ data.word(kCard1money) = 12432;
+ data.byte(kGetback) = 1;
+ return;
+notyet:
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::usecardreader2() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gotreader2with;
+ withwhat();
+ return;
+gotreader2with:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'S';
+ dl = 'H';
+ dh = 'R';
+ compare();
+ if (flags.z())
+ goto correctcard2;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+correctcard2:
+ _cmp(data.byte(kTalkedtoboss), 0);
+ if (flags.z())
+ goto notyetboss;
+ _cmp(data.word(kCard1money), 0);
+ if (flags.z())
+ goto nocash;
+ _cmp(data.byte(kGunpassflag), 2);
+ if (flags.z())
+ goto alreadygotnew;
+ al = 18;
+ playchannel1();
+ cx = 300;
+ al = 19;
+ showpuztext();
+ al = 94;
+ placesetobject();
+ data.byte(kGunpassflag) = 1;
+ _sub(data.word(kCard1money), 2000);
+ _inc(data.byte(kProgresspoints));
+ data.byte(kGetback) = 1;
+ return;
+nocash:
+ cx = 300;
+ al = 20;
+ showpuztext();
+ putbackobstuff();
+ return;
+alreadygotnew:
+ cx = 300;
+ al = 22;
+ showpuztext();
+ putbackobstuff();
+ return;
+notyetboss:
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::usecardreader3() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gotreader3with;
+ withwhat();
+ return;
+gotreader3with:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'S';
+ dl = 'H';
+ dh = 'R';
+ compare();
+ if (flags.z())
+ goto rightcard;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+rightcard:
+ _cmp(data.byte(kTalkedtorecep), 0);
+ if (flags.z())
+ goto notyetrecep;
+ _cmp(data.byte(kCardpassflag), 0);
+ if (!flags.z())
+ goto alreadyusedit;
+ al = 16;
+ playchannel1();
+ cx = 300;
+ al = 25;
+ showpuztext();
+ _inc(data.byte(kProgresspoints));
+ _sub(data.word(kCard1money), 8300);
+ data.byte(kCardpassflag) = 1;
+ data.byte(kGetback) = 1;
+ return;
+alreadyusedit:
+ cx = 300;
+ al = 26;
+ showpuztext();
+ putbackobstuff();
+ return;
+notyetrecep:
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::usecashcard() {
+ STACK_CHECK;
+ getridofreels();
+ loadkeypad();
+ createpanel();
+ showpanel();
+ showexit();
+ showman();
+ di = 114;
+ bx = 120;
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ bx = 120-3;
+_tmp1:
+ ds = data.word(kTempgraphics);
+ al = 39;
+ ah = 0;
+ showframe();
+ ax = data.word(kCard1money);
+ moneypoke();
+ getobtextstart();
+ nextcolon();
+ nextcolon();
+ di = 36;
+ bx = 98;
+ dl = 241;
+ al = 0;
+ ah = 0;
+ printdirect();
+ di = 160;
+ bx = 155;
+ es = cs;
+ si = 3474;
+ data.word(kCharshift) = 91*2+75;
+ al = 0;
+ ah = 0;
+ dl = 240;
+ printdirect();
+ di = 187;
+ bx = 155;
+ es = cs;
+ si = 3479;
+ data.word(kCharshift) = 91*2+85;
+ al = 0;
+ ah = 0;
+ dl = 240;
+ printdirect();
+ data.word(kCharshift) = 0;
+ worktoscreenm();
+ cx = 400;
+ hangonp();
+ getridoftemp();
+ restorereels();
+ putbackobstuff();
+}
+
+void DreamGenContext::lookatcard() {
+ STACK_CHECK;
+ data.byte(kManisoffscreen) = 1;
+ getridofreels();
+ loadkeypad();
+ createpanel2();
+ di = 160;
+ bx = 80;
+ ds = data.word(kTempgraphics);
+ al = 42;
+ ah = 128;
+ showframe();
+ getobtextstart();
+ findnextcolon();
+ findnextcolon();
+ findnextcolon();
+ di = 36;
+ bx = 124;
+ dl = 241;
+ al = 0;
+ ah = 0;
+ printdirect();
+ push(es);
+ push(si);
+ worktoscreenm();
+ cx = 280;
+ hangonw();
+ createpanel2();
+ di = 160;
+ bx = 80;
+ ds = data.word(kTempgraphics);
+ al = 42;
+ ah = 128;
+ showframe();
+ si = pop();
+ es = pop();
+ di = 36;
+ bx = 130;
+ dl = 241;
+ al = 0;
+ ah = 0;
+ printdirect();
+ worktoscreenm();
+ cx = 200;
+ hangonw();
+ data.byte(kManisoffscreen) = 0;
+ getridoftemp();
+ restorereels();
+ putbackobstuff();
+}
+
+void DreamGenContext::moneypoke() {
+ STACK_CHECK;
+ bx = 3474;
+ cl = 48-1;
+numberpoke0:
+ _inc(cl);
+ _sub(ax, 10000);
+ if (!flags.c())
+ goto numberpoke0;
+ _add(ax, 10000);
+ cs.byte(bx) = cl;
+ _inc(bx);
+ cl = 48-1;
+numberpoke1:
+ _inc(cl);
+ _sub(ax, 1000);
+ if (!flags.c())
+ goto numberpoke1;
+ _add(ax, 1000);
+ cs.byte(bx) = cl;
+ _inc(bx);
+ cl = 48-1;
+numberpoke2:
+ _inc(cl);
+ _sub(ax, 100);
+ if (!flags.c())
+ goto numberpoke2;
+ _add(ax, 100);
+ cs.byte(bx) = cl;
+ _inc(bx);
+ cl = 48-1;
+numberpoke3:
+ _inc(cl);
+ _sub(ax, 10);
+ if (!flags.c())
+ goto numberpoke3;
+ _add(ax, 10);
+ cs.byte(bx) = cl;
+ bx = 3479;
+ _add(al, 48);
+ cs.byte(bx) = al;
+}
+
+void DreamGenContext::usecontrol() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gotcontrolwith;
+ withwhat();
+ return;
+gotcontrolwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'K';
+ ch = 'E';
+ dl = 'Y';
+ dh = 'A';
+ compare();
+ if (flags.z())
+ goto rightkey;
+ _cmp(data.byte(kReallocation), 21);
+ if (!flags.z())
+ goto balls;
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'K';
+ ch = 'N';
+ dl = 'F';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto jimmycontrols;
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'A';
+ ch = 'X';
+ dl = 'E';
+ dh = 'D';
+ compare();
+ if (flags.z())
+ goto axeoncontrols;
+balls:
+ showfirstuse();
+ putbackobstuff();
+ return;
+rightkey:
+ al = 16;
+ playchannel1();
+ _cmp(data.byte(kLocation), 21);
+ if (flags.z())
+ goto goingdown;
+ cx = 300;
+ al = 0;
+ showpuztext();
+ data.byte(kNewlocation) = 21;
+ data.byte(kCounttoclose) = 8;
+ data.byte(kCounttoopen) = 0;
+ data.word(kWatchingtime) = 80;
+ data.byte(kGetback) = 1;
+ return;
+goingdown:
+ cx = 300;
+ al = 3;
+ showpuztext();
+ data.byte(kNewlocation) = 30;
+ data.byte(kCounttoclose) = 8;
+ data.byte(kCounttoopen) = 0;
+ data.word(kWatchingtime) = 80;
+ data.byte(kGetback) = 1;
+ return;
+jimmycontrols:
+ al = 50;
+ placesetobject();
+ al = 51;
+ placesetobject();
+ al = 26;
+ placesetobject();
+ al = 30;
+ placesetobject();
+ al = 16;
+ removesetobject();
+ al = 17;
+ removesetobject();
+ al = 14;
+ playchannel1();
+ cx = 300;
+ al = 10;
+ showpuztext();
+ _inc(data.byte(kProgresspoints));
+ data.byte(kGetback) = 1;
+ return;
+axeoncontrols:
+ cx = 300;
+ al = 16;
+ showpuztext();
+ _inc(data.byte(kProgresspoints));
+ putbackobstuff();
+}
+
+void DreamGenContext::usehatch() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kNewlocation) = 40;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usewire() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gotwirewith;
+ withwhat();
+ return;
+gotwirewith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'K';
+ ch = 'N';
+ dl = 'F';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto wireknife;
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'A';
+ ch = 'X';
+ dl = 'E';
+ dh = 'D';
+ compare();
+ if (flags.z())
+ goto wireaxe;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+wireaxe:
+ cx = 300;
+ al = 16;
+ showpuztext();
+ putbackobstuff();
+ return;
+wireknife:
+ al = 51;
+ removesetobject();
+ al = 52;
+ placesetobject();
+ cx = 300;
+ al = 11;
+ showpuztext();
+ _inc(data.byte(kProgresspoints));
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usehandle() {
+ STACK_CHECK;
+ al = 'C';
+ ah = 'U';
+ cl = 'T';
+ ch = 'W';
+ findsetobject();
+ al = es.byte(bx+58);
+ _cmp(al, 255);
+ if (!flags.z())
+ goto havecutwire;
+ cx = 300;
+ al = 12;
+ showpuztext();
+ data.byte(kGetback) = 1;
+ return;
+havecutwire:
+ cx = 300;
+ al = 13;
+ showpuztext();
+ data.byte(kNewlocation) = 22;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useelevator1() {
+ STACK_CHECK;
+ showfirstuse();
+ selectlocation();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::showfirstuse() {
+ STACK_CHECK;
+ getobtextstart();
+ findnextcolon();
+ findnextcolon();
+ usetext();
+ cx = 400;
+ hangonp();
+}
+
+void DreamGenContext::useelevator3() {
+ STACK_CHECK;
+ showfirstuse();
+ data.byte(kCounttoclose) = 20;
+ data.byte(kNewlocation) = 34;
+ data.word(kReeltowatch) = 46;
+ data.word(kEndwatchreel) = 63;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.word(kWatchingtime) = 80;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useelevator4() {
+ STACK_CHECK;
+ showfirstuse();
+ data.word(kReeltowatch) = 0;
+ data.word(kEndwatchreel) = 11;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kCounttoclose) = 20;
+ data.word(kWatchingtime) = 80;
+ data.byte(kGetback) = 1;
+ data.byte(kNewlocation) = 24;
+}
+
+void DreamGenContext::useelevator2() {
+ STACK_CHECK;
+ _cmp(data.byte(kLocation), 23);
+ if (flags.z())
+ goto inpoolhall;
+ showfirstuse();
+ data.byte(kNewlocation) = 23;
+ data.byte(kCounttoclose) = 20;
+ data.byte(kCounttoopen) = 0;
+ data.word(kWatchingtime) = 80;
+ data.byte(kGetback) = 1;
+ return;
+inpoolhall:
+ showfirstuse();
+ data.byte(kNewlocation) = 31;
+ data.byte(kCounttoclose) = 20;
+ data.byte(kCounttoopen) = 0;
+ data.word(kWatchingtime) = 80;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useelevator5() {
+ STACK_CHECK;
+ al = 4;
+ placesetobject();
+ al = 0;
+ removesetobject();
+ data.byte(kNewlocation) = 20;
+ data.word(kWatchingtime) = 80;
+ data.byte(kLiftflag) = 1;
+ data.byte(kCounttoclose) = 8;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usekey() {
+ STACK_CHECK;
+ _cmp(data.byte(kLocation), 5);
+ if (flags.z())
+ goto usekey1;
+ _cmp(data.byte(kLocation), 30);
+ if (flags.z())
+ goto usekey1;
+ _cmp(data.byte(kLocation), 21);
+ if (flags.z())
+ goto usekey2;
+ cx = 200;
+ al = 1;
+ showpuztext();
+ putbackobstuff();
+ return;
+usekey1:
+ _cmp(data.byte(kMapx), 22);
+ if (!flags.z())
+ goto wrongroom1;
+ _cmp(data.byte(kMapy), 10);
+ if (!flags.z())
+ goto wrongroom1;
+ cx = 300;
+ al = 0;
+ showpuztext();
+ data.byte(kCounttoclose) = 100;
+ data.byte(kGetback) = 1;
+ return;
+usekey2:
+ _cmp(data.byte(kMapx), 11);
+ if (!flags.z())
+ goto wrongroom1;
+ _cmp(data.byte(kMapy), 10);
+ if (!flags.z())
+ goto wrongroom1;
+ cx = 300;
+ al = 3;
+ showpuztext();
+ data.byte(kNewlocation) = 30;
+ al = 2;
+ fadescreendown();
+ showfirstuse();
+ putbackobstuff();
+ return;
+wrongroom1:
+ cx = 200;
+ al = 2;
+ showpuztext();
+ putbackobstuff();
+}
+
+void DreamGenContext::usestereo() {
+ STACK_CHECK;
+ _cmp(data.byte(kLocation), 0);
+ if (flags.z())
+ goto stereook;
+ cx = 400;
+ al = 4;
+ showpuztext();
+ putbackobstuff();
+ return;
+stereook:
+ _cmp(data.byte(kMapx), 11);
+ if (!flags.z())
+ goto stereonotok;
+ _cmp(data.byte(kMapy), 0);
+ if (flags.z())
+ goto stereook2;
+stereonotok:
+ cx = 400;
+ al = 5;
+ showpuztext();
+ putbackobstuff();
+ return;
+stereook2:
+ al = 'C';
+ ah = 'D';
+ cl = 'P';
+ ch = 'L';
+ findsetobject();
+ ah = 1;
+ checkinside();
+ _cmp(cl, (114));
+ if (!flags.z())
+ goto cdinside;
+ al = 6;
+ cx = 400;
+ showpuztext();
+ putbackobstuff();
+ getanyad();
+ al = 255;
+ es.byte(bx+10) = al;
+ return;
+cdinside:
+ getanyad();
+ al = es.byte(bx+10);
+ _xor(al, 1);
+ es.byte(bx+10) = al;
+ _cmp(al, 255);
+ if (flags.z())
+ goto stereoon;
+ al = 7;
+ cx = 400;
+ showpuztext();
+ putbackobstuff();
+ return;
+stereoon:
+ al = 8;
+ cx = 400;
+ showpuztext();
+ putbackobstuff();
+}
+
+void DreamGenContext::usecooker() {
+ STACK_CHECK;
+ al = data.byte(kCommand);
+ ah = data.byte(kObjecttype);
+ checkinside();
+ _cmp(cl, (114));
+ if (!flags.z())
+ goto foodinside;
+ showfirstuse();
+ putbackobstuff();
+ return;
+foodinside:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::useaxe() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 22);
+ if (!flags.z())
+ goto notinpool;
+ _cmp(data.byte(kMapy), 10);
+ if (flags.z())
+ goto axeondoor;
+ showseconduse();
+ _inc(data.byte(kProgresspoints));
+ data.byte(kLastweapon) = 2;
+ data.byte(kGetback) = 1;
+ removeobfrominv();
+ return;
+notinpool:
+ showfirstuse();
+ return;
+/*continuing to unbounded code: axeondoor from useelvdoor:19-30*/
+axeondoor:
+ al = 15;
+ cx = 300;
+ showpuztext();
+ _inc(data.byte(kProgresspoints));
+ data.word(kWatchingtime) = 46*2;
+ data.word(kReeltowatch) = 31;
+ data.word(kEndwatchreel) = 77;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::useelvdoor() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gotdoorwith;
+ withwhat();
+ return;
+gotdoorwith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'A';
+ ch = 'X';
+ dl = 'E';
+ dh = 'D';
+ compare();
+ if (flags.z())
+ goto axeondoor;
+ al = 14;
+ cx = 300;
+ showpuztext();
+ putbackobstuff();
+ return;
+axeondoor:
+ al = 15;
+ cx = 300;
+ showpuztext();
+ _inc(data.byte(kProgresspoints));
+ data.word(kWatchingtime) = 46*2;
+ data.word(kReeltowatch) = 31;
+ data.word(kEndwatchreel) = 77;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::withwhat() {
+ STACK_CHECK;
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ al = data.byte(kCommand);
+ ah = data.byte(kObjecttype);
+ es = cs;
+ di = 5847;
+ copyname();
+ di = 100;
+ bx = 21;
+ dl = 200;
+ al = 63;
+ ah = 2;
+ printmessage2();
+ di = data.word(kLastxpos);
+ _add(di, 5);
+ bx = 21;
+ es = cs;
+ si = 5847;
+ dl = 220;
+ al = 0;
+ ah = 0;
+ printdirect();
+ di = data.word(kLastxpos);
+ _add(di, 5);
+ bx = 21;
+ dl = 200;
+ al = 63;
+ ah = 3;
+ printmessage2();
+ fillryan();
+ data.byte(kCommandtype) = 255;
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+ data.byte(kInvopen) = 2;
+}
+
+void DreamGenContext::selectob() {
+ STACK_CHECK;
+ findinvpos();
+ ax = es.word(bx);
+ _cmp(al, 255);
+ if (!flags.z())
+ goto canselectob;
+ blank();
+ return;
+canselectob:
+ data.byte(kWithobject) = al;
+ data.byte(kWithtype) = ah;
+ _cmp(ax, data.word(kOldsubject));
+ if (!flags.z())
+ goto diffsub3;
+ _cmp(data.byte(kCommandtype), 221);
+ if (flags.z())
+ goto alreadyselob;
+ data.byte(kCommandtype) = 221;
+diffsub3:
+ data.word(kOldsubject) = ax;
+ bx = ax;
+ al = 0;
+ commandwithob();
+alreadyselob:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notselob) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doselob;
+ return;
+doselob:
+ delpointer();
+ data.byte(kInvopen) = 0;
+ useroutine();
+}
+
+void DreamGenContext::compare() {
+ STACK_CHECK;
+ _sub(dl, 'A');
+ _sub(dh, 'A');
+ _sub(cl, 'A');
+ _sub(ch, 'A');
+ push(cx);
+ push(dx);
+ getanyaddir();
+ dx = pop();
+ cx = pop();
+ _cmp(es.word(bx+12), cx);
+ if (!flags.z())
+ return /* (comparefin) */;
+ _cmp(es.word(bx+14), dx);
+}
+
+void DreamGenContext::findsetobject() {
+ STACK_CHECK;
+ _sub(al, 'A');
+ _sub(ah, 'A');
+ _sub(cl, 'A');
+ _sub(ch, 'A');
+ es = data.word(kSetdat);
+ bx = 0;
+ dl = 0;
+findsetloop:
+ _cmp(al, es.byte(bx+12));
+ if (!flags.z())
+ goto nofind;
+ _cmp(ah, es.byte(bx+13));
+ if (!flags.z())
+ goto nofind;
+ _cmp(cl, es.byte(bx+14));
+ if (!flags.z())
+ goto nofind;
+ _cmp(ch, es.byte(bx+15));
+ if (!flags.z())
+ goto nofind;
+ al = dl;
+ return;
+nofind:
+ _add(bx, 64);
+ _inc(dl);
+ _cmp(dl, 128);
+ if (!flags.z())
+ goto findsetloop;
+ al = dl;
+}
+
+void DreamGenContext::findexobject() {
+ STACK_CHECK;
+ _sub(al, 'A');
+ _sub(ah, 'A');
+ _sub(cl, 'A');
+ _sub(ch, 'A');
+ es = data.word(kExtras);
+ bx = (0+2080+30000);
+ dl = 0;
+findexloop:
+ _cmp(al, es.byte(bx+12));
+ if (!flags.z())
+ goto nofindex;
+ _cmp(ah, es.byte(bx+13));
+ if (!flags.z())
+ goto nofindex;
+ _cmp(cl, es.byte(bx+14));
+ if (!flags.z())
+ goto nofindex;
+ _cmp(ch, es.byte(bx+15));
+ if (!flags.z())
+ goto nofindex;
+ al = dl;
+ return;
+nofindex:
+ _add(bx, 16);
+ _inc(dl);
+ _cmp(dl, (114));
+ if (!flags.z())
+ goto findexloop;
+ al = dl;
+}
+
+void DreamGenContext::isryanholding() {
+ STACK_CHECK;
+ _sub(al, 'A');
+ _sub(ah, 'A');
+ _sub(cl, 'A');
+ _sub(ch, 'A');
+ es = data.word(kExtras);
+ bx = (0+2080+30000);
+ dl = 0;
+searchinv:
+ _cmp(es.byte(bx+2), 4);
+ if (!flags.z())
+ goto nofindininv;
+ _cmp(al, es.byte(bx+12));
+ if (!flags.z())
+ goto nofindininv;
+ _cmp(ah, es.byte(bx+13));
+ if (!flags.z())
+ goto nofindininv;
+ _cmp(cl, es.byte(bx+14));
+ if (!flags.z())
+ goto nofindininv;
+ _cmp(ch, es.byte(bx+15));
+ if (!flags.z())
+ goto nofindininv;
+ al = dl;
+ _cmp(al, (114));
+ return;
+nofindininv:
+ _add(bx, 16);
+ _inc(dl);
+ _cmp(dl, (114));
+ if (!flags.z())
+ goto searchinv;
+ al = dl;
+ _cmp(al, (114));
+}
+
+void DreamGenContext::checkinside() {
+ STACK_CHECK;
+ es = data.word(kExtras);
+ bx = (0+2080+30000);
+ cl = 0;
+insideloop:
+ _cmp(al, es.byte(bx+3));
+ if (!flags.z())
+ goto notfoundinside;
+ _cmp(ah, es.byte(bx+2));
+ if (!flags.z())
+ goto notfoundinside;
+ return;
+notfoundinside:
+ _add(bx, 16);
+ _inc(cl);
+ _cmp(cl, (114));
+ if (!flags.z())
+ goto insideloop;
+}
+
+void DreamGenContext::usetext() {
+ STACK_CHECK;
+ push(es);
+ push(si);
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ obicons();
+ si = pop();
+ es = pop();
+ di = 36;
+ bx = 104;
+ dl = 241;
+ al = 0;
+ ah = 0;
+ printdirect();
+ worktoscreenm();
+}
+
+void DreamGenContext::putbackobstuff() {
+ STACK_CHECK;
+ createpanel();
+ showpanel();
+ showman();
+ obicons();
+ showexit();
+ obpicture();
+ describeob();
+ undertextline();
+ data.byte(kCommandtype) = 255;
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::showpuztext() {
+ STACK_CHECK;
+ push(cx);
+ findpuztext();
+ push(es);
+ push(si);
+ createpanel();
+ showpanel();
+ showman();
+ showexit();
+ obicons();
+ si = pop();
+ es = pop();
+ di = 36;
+ bx = 104;
+ dl = 241;
+ ah = 0;
+ printdirect();
+ worktoscreenm();
+ cx = pop();
+ hangonp();
+}
+
+void DreamGenContext::findpuztext() {
+ STACK_CHECK;
+ ah = 0;
+ si = ax;
+ _add(si, si);
+ es = data.word(kPuzzletext);
+ ax = es.word(si);
+ _add(ax, (66*2));
+ si = ax;
+}
+
+void DreamGenContext::placesetobject() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ cl = 0;
+ ch = 0;
+ findormake();
+ getsetad();
+ es.byte(bx+58) = 0;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::removesetobject() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ cl = 255;
+ ch = 0;
+ findormake();
+ getsetad();
+ es.byte(bx+58) = 255;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::issetobonmap() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ getsetad();
+ al = es.byte(bx+58);
+ bx = pop();
+ es = pop();
+ _cmp(al, 0);
+}
+
+void DreamGenContext::placefreeobject() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ cl = 0;
+ ch = 1;
+ findormake();
+ getfreead();
+ es.byte(bx+2) = 0;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::removefreeobject() {
+ STACK_CHECK;
+ push(es);
+ push(bx);
+ getfreead();
+ es.byte(bx+2) = 255;
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::findormake() {
+ STACK_CHECK;
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80));
+ push(ax);
+ es = data.word(kBuffers);
+ ah = data.byte(kReallocation);
+changeloop:
+ _cmp(es.byte(bx), 255);
+ if (flags.z())
+ goto haventfound;
+ _cmp(ax, es.word(bx));
+ if (!flags.z())
+ goto nofoundchange;
+ _cmp(ch, es.byte(bx+3));
+ if (flags.z())
+ goto foundchange;
+nofoundchange:
+ _add(bx, 4);
+ goto changeloop;
+foundchange:
+ ax = pop();
+ es.byte(bx+2) = cl;
+ return;
+haventfound:
+ es.word(bx) = ax;
+ es.word(bx+2) = cx;
+ ax = pop();
+}
+
+void DreamGenContext::switchryanon() {
+ STACK_CHECK;
+ data.byte(kRyanon) = 255;
+}
+
+void DreamGenContext::switchryanoff() {
+ STACK_CHECK;
+ data.byte(kRyanon) = 1;
+}
+
+void DreamGenContext::setallchanges() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80));
+setallloop:
+ ax = es.word(bx);
+ _cmp(al, 255);
+ if (flags.z())
+ return /* (endsetloop) */;
+ cx = es.word(bx+2);
+ _add(bx, 4);
+ _cmp(ah, data.byte(kReallocation));
+ if (!flags.z())
+ goto setallloop;
+ push(es);
+ push(bx);
+ dochange();
+ bx = pop();
+ es = pop();
+ goto setallloop;
+}
+
+void DreamGenContext::dochange() {
+ STACK_CHECK;
+ _cmp(ch, 0);
+ if (flags.z())
+ goto object;
+ _cmp(ch, 1);
+ if (flags.z())
+ goto freeobject;
+ push(cx);
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ push(ax);
+ al = ch;
+ _sub(al, 100);
+ ah = 0;
+ cx = 144;
+ _mul(cx);
+ bx = pop();
+ _add(bx, ax);
+ _add(bx, (0));
+ es = data.word(kReels);
+ cx = pop();
+ es.byte(bx+6) = cl;
+ return;
+object:
+ push(cx);
+ getsetad();
+ cx = pop();
+ es.byte(bx+58) = cl;
+ return;
+freeobject:
+ push(cx);
+ getfreead();
+ cx = pop();
+ _cmp(es.byte(bx+2), 255);
+ if (!flags.z())
+ return /* (beenpickedup) */;
+ es.byte(bx+2) = cl;
+}
+
+void DreamGenContext::autoappear() {
+ STACK_CHECK;
+ _cmp(data.byte(kLocation), 32);
+ if (!flags.z())
+ goto notinalley;
+ al = 5;
+ resetlocation();
+ al = 10;
+ setlocation();
+ data.byte(kDestpos) = 10;
+ return;
+notinalley:
+ _cmp(data.byte(kReallocation), 24);
+ if (!flags.z())
+ goto notinedens;
+ _cmp(data.byte(kGeneraldead), 1);
+ if (!flags.z())
+ goto edenspart2;
+ _inc(data.byte(kGeneraldead));
+ al = 44;
+ placesetobject();
+ al = 18;
+ placesetobject();
+ al = 93;
+ placesetobject();
+ al = 92;
+ removesetobject();
+ al = 55;
+ removesetobject();
+ al = 75;
+ removesetobject();
+ al = 84;
+ removesetobject();
+ al = 85;
+ removesetobject();
+ return;
+edenspart2:
+ _cmp(data.byte(kSartaindead), 1);
+ if (!flags.z())
+ return /* (notedens2) */;
+ al = 44;
+ removesetobject();
+ al = 93;
+ removesetobject();
+ al = 55;
+ placesetobject();
+ _inc(data.byte(kSartaindead));
+ return;
+notinedens:
+ _cmp(data.byte(kReallocation), 25);
+ if (!flags.z())
+ goto notonsartroof;
+ data.byte(kNewsitem) = 3;
+ al = 6;
+ resetlocation();
+ al = 11;
+ setlocation();
+ data.byte(kDestpos) = 11;
+ return;
+notonsartroof:
+ _cmp(data.byte(kReallocation), 2);
+ if (!flags.z())
+ return /* (notinlouiss) */;
+ _cmp(data.byte(kRockstardead), 0);
+ if (flags.z())
+ return /* (notinlouiss) */;
+ al = 23;
+ placesetobject();
+}
+
+void DreamGenContext::getundertimed() {
+ STACK_CHECK;
+ al = data.byte(kTimedy);
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(al, 3);
+_tmp1:
+ ah = 0;
+ bx = ax;
+ al = data.byte(kTimedx);
+ ah = 0;
+ di = ax;
+ ch = (30);
+ cl = 240;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4));
+ multiget();
+}
+
+void DreamGenContext::putundertimed() {
+ STACK_CHECK;
+ al = data.byte(kTimedy);
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(al, 3);
+_tmp1:
+ ah = 0;
+ bx = ax;
+ al = data.byte(kTimedx);
+ ah = 0;
+ di = ax;
+ ch = (30);
+ cl = 240;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4));
+ multiput();
+}
+
+void DreamGenContext::dumptimedtext() {
+ STACK_CHECK;
+ _cmp(data.byte(kNeedtodumptimed), 1);
+ if (!flags.z())
+ return /* (nodumptimed) */;
+ al = data.byte(kTimedy);
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(al, 3);
+_tmp1:
+ ah = 0;
+ bx = ax;
+ al = data.byte(kTimedx);
+ ah = 0;
+ di = ax;
+ cl = 240;
+ ch = (30);
+ multidump();
+ data.byte(kNeedtodumptimed) = 0;
+}
+
+void DreamGenContext::setuptimeduse() {
+ STACK_CHECK;
+ _cmp(data.word(kTimecount), 0);
+ if (!flags.z())
+ return /* (cantsetup) */;
+ data.byte(kTimedy) = bh;
+ data.byte(kTimedx) = bl;
+ data.word(kCounttotimed) = cx;
+ _add(dx, cx);
+ data.word(kTimecount) = dx;
+ bl = al;
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kPuzzletext);
+ cx = (66*2);
+ ax = es.word(bx);
+ _add(ax, cx);
+ bx = ax;
+ data.word(kTimedseg) = es;
+ data.word(kTimedoffset) = bx;
+}
+
+void DreamGenContext::setuptimedtemp() {
+ STACK_CHECK;
+ _cmp(ah, 0);
+ if (flags.z())
+ goto notloadspeech3;
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ dl = 'T';
+ dh = ah;
+ cl = 'T';
+ ah = 0;
+ loadspeech();
+ _cmp(data.byte(kSpeechloaded), 1);
+ if (!flags.z())
+ goto _tmp1;
+ al = 50+12;
+ playchannel1();
+_tmp1:
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+ _cmp(data.byte(kSpeechloaded), 1);
+ if (!flags.z())
+ goto notloadspeech3;
+ _cmp(data.byte(kSubtitles), 1);
+ if (flags.z())
+ goto notloadspeech3;
+ return;
+notloadspeech3:
+ _cmp(data.word(kTimecount), 0);
+ if (!flags.z())
+ return /* (cantsetup2) */;
+ data.byte(kTimedy) = bh;
+ data.byte(kTimedx) = bl;
+ data.word(kCounttotimed) = cx;
+ _add(dx, cx);
+ data.word(kTimecount) = dx;
+ bl = al;
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kTextfile1);
+ cx = (66*2);
+ ax = es.word(bx);
+ _add(ax, cx);
+ bx = ax;
+ data.word(kTimedseg) = es;
+ data.word(kTimedoffset) = bx;
+}
+
+void DreamGenContext::usetimedtext() {
+ STACK_CHECK;
+ _cmp(data.word(kTimecount), 0);
+ if (flags.z())
+ return /* (notext) */;
+ _dec(data.word(kTimecount));
+ _cmp(data.word(kTimecount), 0);
+ if (flags.z())
+ goto deltimedtext;
+ ax = data.word(kTimecount);
+ _cmp(ax, data.word(kCounttotimed));
+ if (flags.z())
+ goto firsttimed;
+ if (!flags.c())
+ return /* (notext) */;
+ goto notfirsttimed;
+firsttimed:
+ getundertimed();
+notfirsttimed:
+ bl = data.byte(kTimedy);
+ bh = 0;
+ al = data.byte(kTimedx);
+ ah = 0;
+ di = ax;
+ es = data.word(kTimedseg);
+ si = data.word(kTimedoffset);
+ dl = 237;
+ ah = 0;
+ printdirect();
+ data.byte(kNeedtodumptimed) = 1;
+ return;
+deltimedtext:
+ putundertimed();
+ data.byte(kNeedtodumptimed) = 1;
+}
+
+void DreamGenContext::edenscdplayer() {
+ STACK_CHECK;
+ showfirstuse();
+ data.word(kWatchingtime) = 18*2;
+ data.word(kReeltowatch) = 25;
+ data.word(kEndwatchreel) = 42;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::usewall() {
+ STACK_CHECK;
+ showfirstuse();
+ _cmp(data.byte(kManspath), 3);
+ if (flags.z())
+ goto gobackover;
+ data.word(kWatchingtime) = 30*2;
+ data.word(kReeltowatch) = 2;
+ data.word(kEndwatchreel) = 31;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ al = 3;
+ turnpathon();
+ al = 4;
+ turnpathon();
+ al = 0;
+ turnpathoff();
+ al = 1;
+ turnpathoff();
+ al = 2;
+ turnpathoff();
+ al = 5;
+ turnpathoff();
+ data.byte(kManspath) = 3;
+ data.byte(kFinaldest) = 3;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ switchryanoff();
+ return;
+gobackover:
+ data.word(kWatchingtime) = 30*2;
+ data.word(kReeltowatch) = 34;
+ data.word(kEndwatchreel) = 60;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ al = 3;
+ turnpathoff();
+ al = 4;
+ turnpathoff();
+ al = 0;
+ turnpathon();
+ al = 1;
+ turnpathon();
+ al = 2;
+ turnpathon();
+ al = 5;
+ turnpathon();
+ data.byte(kManspath) = 5;
+ data.byte(kFinaldest) = 5;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ switchryanoff();
+}
+
+void DreamGenContext::usechurchgate() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto gatewith;
+ withwhat();
+ return;
+gatewith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'C';
+ ch = 'U';
+ dl = 'T';
+ dh = 'T';
+ compare();
+ if (flags.z())
+ goto cutgate;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+cutgate:
+ showfirstuse();
+ data.word(kWatchingtime) = 64*2;
+ data.word(kReeltowatch) = 4;
+ data.word(kEndwatchreel) = 70;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ _inc(data.byte(kProgresspoints));
+ al = 3;
+ turnpathon();
+ _cmp(data.byte(kAidedead), 0);
+ if (flags.z())
+ return /* (notopenchurch) */;
+ al = 2;
+ turnpathon();
+}
+
+void DreamGenContext::usegun() {
+ STACK_CHECK;
+ _cmp(data.byte(kObjecttype), 4);
+ if (flags.z())
+ goto istakengun;
+ showseconduse();
+ putbackobstuff();
+ return;
+istakengun:
+ _cmp(data.byte(kReallocation), 22);
+ if (!flags.z())
+ goto notinpoolroom;
+ cx = 300;
+ al = 34;
+ showpuztext();
+ data.byte(kLastweapon) = 1;
+ data.byte(kCombatcount) = 39;
+ data.byte(kGetback) = 1;
+ _inc(data.byte(kProgresspoints));
+ return;
+notinpoolroom:
+ _cmp(data.byte(kReallocation), 25);
+ if (!flags.z())
+ goto nothelicopter;
+ cx = 300;
+ al = 34;
+ showpuztext();
+ data.byte(kLastweapon) = 1;
+ data.byte(kCombatcount) = 19;
+ data.byte(kGetback) = 1;
+ data.byte(kDreamnumber) = 2;
+ data.byte(kRoomafterdream) = 38;
+ data.byte(kSartaindead) = 1;
+ _inc(data.byte(kProgresspoints));
+ return;
+nothelicopter:
+ _cmp(data.byte(kReallocation), 27);
+ if (!flags.z())
+ goto notinrockroom;
+ cx = 300;
+ al = 46;
+ showpuztext();
+ data.byte(kPointermode) = 2;
+ data.byte(kRockstardead) = 1;
+ data.byte(kLastweapon) = 1;
+ data.byte(kNewsitem) = 1;
+ data.byte(kGetback) = 1;
+ data.byte(kRoomafterdream) = 32;
+ data.byte(kDreamnumber) = 0;
+ _inc(data.byte(kProgresspoints));
+ return;
+notinrockroom:
+ _cmp(data.byte(kReallocation), 8);
+ if (!flags.z())
+ goto notbystudio;
+ _cmp(data.byte(kMapx), 22);
+ if (!flags.z())
+ goto notbystudio;
+ _cmp(data.byte(kMapy), 40);
+ if (!flags.z())
+ goto notbystudio;
+ al = 92;
+ issetobonmap();
+ if (flags.z())
+ goto notbystudio;
+ _cmp(data.byte(kManspath), 9);
+ if (flags.z())
+ goto notbystudio;
+ data.byte(kDestination) = 9;
+ data.byte(kFinaldest) = 9;
+ autosetwalk();
+ data.byte(kLastweapon) = 1;
+ data.byte(kGetback) = 1;
+ _inc(data.byte(kProgresspoints));
+ return;
+notbystudio:
+ _cmp(data.byte(kReallocation), 6);
+ if (!flags.z())
+ goto notsarters;
+ _cmp(data.byte(kMapx), 11);
+ if (!flags.z())
+ goto notsarters;
+ _cmp(data.byte(kMapy), 20);
+ if (!flags.z())
+ goto notsarters;
+ al = 5;
+ issetobonmap();
+ if (!flags.z())
+ goto notsarters;
+ data.byte(kDestination) = 1;
+ data.byte(kFinaldest) = 1;
+ autosetwalk();
+ al = 5;
+ removesetobject();
+ al = 6;
+ placesetobject();
+ al = 1;
+ ah = data.byte(kRoomnum);
+ _dec(ah);
+ turnanypathon();
+ data.byte(kLiftflag) = 1;
+ data.word(kWatchingtime) = 40*2;
+ data.word(kReeltowatch) = 4;
+ data.word(kEndwatchreel) = 43;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ _inc(data.byte(kProgresspoints));
+ return;
+notsarters:
+ _cmp(data.byte(kReallocation), 29);
+ if (!flags.z())
+ goto notaide;
+ data.byte(kGetback) = 1;
+ al = 13;
+ resetlocation();
+ al = 12;
+ setlocation();
+ data.byte(kDestpos) = 12;
+ data.byte(kDestination) = 2;
+ data.byte(kFinaldest) = 2;
+ autosetwalk();
+ data.word(kWatchingtime) = 164*2;
+ data.word(kReeltowatch) = 3;
+ data.word(kEndwatchreel) = 164;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kAidedead) = 1;
+ data.byte(kDreamnumber) = 3;
+ data.byte(kRoomafterdream) = 33;
+ _inc(data.byte(kProgresspoints));
+ return;
+notaide:
+ _cmp(data.byte(kReallocation), 23);
+ if (!flags.z())
+ goto notwithboss;
+ _cmp(data.byte(kMapx), 0);
+ if (!flags.z())
+ goto notwithboss;
+ _cmp(data.byte(kMapy), 50);
+ if (!flags.z())
+ goto notwithboss;
+ _cmp(data.byte(kManspath), 5);
+ if (flags.z())
+ goto pathokboss;
+ data.byte(kDestination) = 5;
+ data.byte(kFinaldest) = 5;
+ autosetwalk();
+pathokboss:
+ data.byte(kLastweapon) = 1;
+ data.byte(kGetback) = 1;
+ return;
+notwithboss:
+ _cmp(data.byte(kReallocation), 8);
+ if (!flags.z())
+ goto nottvsoldier;
+ _cmp(data.byte(kMapx), 11);
+ if (!flags.z())
+ goto nottvsoldier;
+ _cmp(data.byte(kMapy), 10);
+ if (!flags.z())
+ goto nottvsoldier;
+ _cmp(data.byte(kManspath), 2);
+ if (flags.z())
+ goto pathoktv;
+ data.byte(kDestination) = 2;
+ data.byte(kFinaldest) = 2;
+ autosetwalk();
+pathoktv:
+ data.byte(kLastweapon) = 1;
+ data.byte(kGetback) = 1;
+ return;
+nottvsoldier:
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::useshield() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 20);
+ if (!flags.z())
+ goto notinsartroom;
+ _cmp(data.byte(kCombatcount), 0);
+ if (flags.z())
+ goto notinsartroom;
+ data.byte(kLastweapon) = 3;
+ showseconduse();
+ data.byte(kGetback) = 1;
+ _inc(data.byte(kProgresspoints));
+ removeobfrominv();
+ return;
+notinsartroom:
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::usebuttona() {
+ STACK_CHECK;
+ al = 95;
+ issetobonmap();
+ if (flags.z())
+ goto donethisbit;
+ showfirstuse();
+ al = 0;
+ ah = data.byte(kRoomnum);
+ _dec(ah);
+ turnanypathon();
+ al = 9;
+ removesetobject();
+ al = 95;
+ placesetobject();
+ data.word(kWatchingtime) = 15*2;
+ data.word(kReeltowatch) = 71;
+ data.word(kEndwatchreel) = 85;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kGetback) = 1;
+ _inc(data.byte(kProgresspoints));
+ return;
+donethisbit:
+ showseconduse();
+ putbackobstuff();
+}
+
+void DreamGenContext::useplate() {
+ STACK_CHECK;
+ _cmp(data.byte(kWithobject), 255);
+ if (!flags.z())
+ goto platewith;
+ withwhat();
+ return;
+platewith:
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'S';
+ ch = 'C';
+ dl = 'R';
+ dh = 'W';
+ compare();
+ if (flags.z())
+ goto unscrewplate;
+ al = data.byte(kWithobject);
+ ah = data.byte(kWithtype);
+ cl = 'K';
+ ch = 'N';
+ dl = 'F';
+ dh = 'E';
+ compare();
+ if (flags.z())
+ goto triedknife;
+ cx = 300;
+ al = 14;
+ showpuztext();
+ putbackobstuff();
+ return;
+unscrewplate:
+ al = 20;
+ playchannel1();
+ showfirstuse();
+ al = 28;
+ placesetobject();
+ al = 24;
+ placesetobject();
+ al = 25;
+ removesetobject();
+ al = 0;
+ placefreeobject();
+ _inc(data.byte(kProgresspoints));
+ data.byte(kGetback) = 1;
+ return;
+triedknife:
+ cx = 300;
+ al = 54;
+ showpuztext();
+ putbackobstuff();
+}
+
+void DreamGenContext::usewinch() {
+ STACK_CHECK;
+ al = 40;
+ ah = 1;
+ checkinside();
+ _cmp(cl, (114));
+ if (flags.z())
+ goto nowinch;
+ al = cl;
+ ah = 4;
+ cl = 'F';
+ ch = 'U';
+ dl = 'S';
+ dh = 'E';
+ compare();
+ if (!flags.z())
+ goto nowinch;
+ data.word(kWatchingtime) = 217*2;
+ data.word(kReeltowatch) = 0;
+ data.word(kEndwatchreel) = 217;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ data.byte(kDestpos) = 1;
+ data.byte(kNewlocation) = 45;
+ data.byte(kDreamnumber) = 1;
+ data.byte(kRoomafterdream) = 44;
+ data.byte(kGeneraldead) = 1;
+ data.byte(kNewsitem) = 2;
+ data.byte(kGetback) = 1;
+ _inc(data.byte(kProgresspoints));
+ return;
+nowinch:
+ showfirstuse();
+ putbackobstuff();
+}
+
+void DreamGenContext::entercode() {
+ STACK_CHECK;
+ data.word(kKeypadax) = ax;
+ data.word(kKeypadcx) = cx;
+ getridofreels();
+ loadkeypad();
+ createpanel();
+ showicon();
+ showouterpad();
+ showkeypad();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+ data.word(kPresspointer) = 0;
+ data.byte(kGetback) = 0;
+keypadloop:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ goto numberright;
+ delpointer();
+ readmouse();
+ showkeypad();
+ showpointer();
+ vsync();
+ _cmp(data.byte(kPresscount), 0);
+ if (flags.z())
+ goto nopresses;
+ _dec(data.byte(kPresscount));
+ goto afterpress;
+nopresses:
+ data.byte(kPressed) = 255;
+ data.byte(kGraphicpress) = 255;
+ vsync();
+afterpress:
+ dumppointer();
+ dumpkeypad();
+ dumptextline();
+ bx = 3482;
+ checkcoords();
+ _cmp(data.byte(kGetback), 1);
+ if (flags.z())
+ goto numberright;
+ _cmp(data.byte(kLightcount), 1);
+ if (!flags.z())
+ goto notendkey;
+ _cmp(data.byte(kLockstatus), 0);
+ if (flags.z())
+ goto numberright;
+ goto keypadloop;
+notendkey:
+ _cmp(data.byte(kPresscount), 40);
+ if (!flags.z())
+ goto keypadloop;
+ addtopresslist();
+ _cmp(data.byte(kPressed), 11);
+ if (!flags.z())
+ goto keypadloop;
+ ax = data.word(kKeypadax);
+ cx = data.word(kKeypadcx);
+ isitright();
+ if (!flags.z())
+ goto incorrect;
+ data.byte(kLockstatus) = 0;
+ al = 11;
+ playchannel1();
+ data.byte(kLightcount) = 120;
+ data.word(kPresspointer) = 0;
+ goto keypadloop;
+incorrect:
+ al = 11;
+ playchannel1();
+ data.byte(kLightcount) = 120;
+ data.word(kPresspointer) = 0;
+ goto keypadloop;
+numberright:
+ data.byte(kManisoffscreen) = 0;
+ getridoftemp();
+ restorereels();
+ redrawmainscrn();
+ worktoscreenm();
+}
+
+void DreamGenContext::loadkeypad() {
+ STACK_CHECK;
+ dx = 1948;
+ loadintotemp();
+}
+
+void DreamGenContext::quitkey() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 222);
+ if (flags.z())
+ goto alreadyqk;
+ data.byte(kCommandtype) = 222;
+ al = 4;
+ commandonly();
+alreadyqk:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notqk) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doqk;
+ return;
+doqk:
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::addtopresslist() {
+ STACK_CHECK;
+ _cmp(data.word(kPresspointer), 5);
+ if (flags.z())
+ return /* (nomorekeys) */;
+ al = data.byte(kPressed);
+ _cmp(al, 10);
+ if (!flags.z())
+ goto not10;
+ al = 0;
+not10:
+ bx = data.word(kPresspointer);
+ dx = data;
+ es = dx;
+ _add(bx, 8573);
+ es.byte(bx) = al;
+ _inc(data.word(kPresspointer));
+}
+
+void DreamGenContext::buttonone() {
+ STACK_CHECK;
+ cl = 1;
+ buttonpress();
+}
+
+void DreamGenContext::buttontwo() {
+ STACK_CHECK;
+ cl = 2;
+ buttonpress();
+}
+
+void DreamGenContext::buttonthree() {
+ STACK_CHECK;
+ cl = 3;
+ buttonpress();
+}
+
+void DreamGenContext::buttonfour() {
+ STACK_CHECK;
+ cl = 4;
+ buttonpress();
+}
+
+void DreamGenContext::buttonfive() {
+ STACK_CHECK;
+ cl = 5;
+ buttonpress();
+}
+
+void DreamGenContext::buttonsix() {
+ STACK_CHECK;
+ cl = 6;
+ buttonpress();
+}
+
+void DreamGenContext::buttonseven() {
+ STACK_CHECK;
+ cl = 7;
+ buttonpress();
+}
+
+void DreamGenContext::buttoneight() {
+ STACK_CHECK;
+ cl = 8;
+ buttonpress();
+}
+
+void DreamGenContext::buttonnine() {
+ STACK_CHECK;
+ cl = 9;
+ buttonpress();
+}
+
+void DreamGenContext::buttonnought() {
+ STACK_CHECK;
+ cl = 10;
+ buttonpress();
+}
+
+void DreamGenContext::buttonenter() {
+ STACK_CHECK;
+ cl = 11;
+ buttonpress();
+}
+
+void DreamGenContext::buttonpress() {
+ STACK_CHECK;
+ ch = cl;
+ _add(ch, 100);
+ _cmp(data.byte(kCommandtype), ch);
+ if (flags.z())
+ goto alreadyb;
+ data.byte(kCommandtype) = ch;
+ al = cl;
+ _add(al, 4);
+ push(cx);
+ commandonly();
+ cx = pop();
+alreadyb:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notb) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto dob;
+ return;
+dob:
+ data.byte(kPressed) = cl;
+ _add(cl, 21);
+ data.byte(kGraphicpress) = cl;
+ data.byte(kPresscount) = 40;
+ _cmp(cl, 32);
+ if (flags.z())
+ return /* (nonoise) */;
+ al = 10;
+ playchannel1();
+}
+
+void DreamGenContext::showouterpad() {
+ STACK_CHECK;
+ di = (36+112)-3;
+ bx = (72)-4;
+ ds = data.word(kTempgraphics);
+ al = 1;
+ ah = 0;
+ showframe();
+ di = (36+112)+74;
+ bx = (72)+76;
+ ds = data.word(kTempgraphics);
+ al = 37;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::showkeypad() {
+ STACK_CHECK;
+ al = 22;
+ di = (36+112)+9;
+ bx = (72)+5;
+ singlekey();
+ al = 23;
+ di = (36+112)+31;
+ bx = (72)+5;
+ singlekey();
+ al = 24;
+ di = (36+112)+53;
+ bx = (72)+5;
+ singlekey();
+ al = 25;
+ di = (36+112)+9;
+ bx = (72)+23;
+ singlekey();
+ al = 26;
+ di = (36+112)+31;
+ bx = (72)+23;
+ singlekey();
+ al = 27;
+ di = (36+112)+53;
+ bx = (72)+23;
+ singlekey();
+ al = 28;
+ di = (36+112)+9;
+ bx = (72)+41;
+ singlekey();
+ al = 29;
+ di = (36+112)+31;
+ bx = (72)+41;
+ singlekey();
+ al = 30;
+ di = (36+112)+53;
+ bx = (72)+41;
+ singlekey();
+ al = 31;
+ di = (36+112)+9;
+ bx = (72)+59;
+ singlekey();
+ al = 32;
+ di = (36+112)+31;
+ bx = (72)+59;
+ singlekey();
+ _cmp(data.byte(kLightcount), 0);
+ if (flags.z())
+ return /* (notenter) */;
+ _dec(data.byte(kLightcount));
+ al = 36;
+ bx = (72)-1+63;
+ _cmp(data.byte(kLockstatus), 0);
+ if (!flags.z())
+ goto changelight;
+ al = 41;
+ bx = (72)+4+63;
+changelight:
+ _cmp(data.byte(kLightcount), 60);
+ if (flags.c())
+ goto gotlight;
+ _cmp(data.byte(kLightcount), 100);
+ if (!flags.c())
+ goto gotlight;
+ _dec(al);
+gotlight:
+ ds = data.word(kTempgraphics);
+ ah = 0;
+ di = (36+112)+60;
+ showframe();
+}
+
+void DreamGenContext::singlekey() {
+ STACK_CHECK;
+ _cmp(data.byte(kGraphicpress), al);
+ if (!flags.z())
+ goto gotkey;
+ _add(al, 11);
+ _cmp(data.byte(kPresscount), 8);
+ if (!flags.c())
+ goto gotkey;
+ _sub(al, 11);
+gotkey:
+ ds = data.word(kTempgraphics);
+ _sub(al, 20);
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::dumpkeypad() {
+ STACK_CHECK;
+ di = (36+112)-3;
+ bx = (72)-4;
+ cl = 120;
+ ch = 90;
+ multidump();
+}
+
+void DreamGenContext::usemenu() {
+ STACK_CHECK;
+ getridofreels();
+ loadmenu();
+ createpanel();
+ showpanel();
+ showicon();
+ data.byte(kNewobs) = 0;
+ drawfloor();
+ printsprites();
+ al = 4;
+ ah = 0;
+ di = (80+40)-48;
+ bx = (60)-4;
+ ds = data.word(kTempgraphics2);
+ showframe();
+ getundermenu();
+ al = 5;
+ ah = 0;
+ di = (80+40)+54;
+ bx = (60)+72;
+ ds = data.word(kTempgraphics2);
+ showframe();
+ worktoscreenm();
+ data.byte(kGetback) = 0;
+menuloop:
+ delpointer();
+ putundermenu();
+ showmenu();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumpmenu();
+ dumptextline();
+ bx = 3614;
+ checkcoords();
+ _cmp(data.byte(kGetback), 1);
+ if (!flags.z())
+ goto menuloop;
+ data.byte(kManisoffscreen) = 0;
+ redrawmainscrn();
+ getridoftemp();
+ getridoftemp2();
+ restorereels();
+ worktoscreenm();
+}
+
+void DreamGenContext::dumpmenu() {
+ STACK_CHECK;
+ di = (80+40);
+ bx = (60);
+ cl = 48;
+ ch = 48;
+ multidump();
+}
+
+void DreamGenContext::getundermenu() {
+ STACK_CHECK;
+ di = (80+40);
+ bx = (60);
+ cl = 48;
+ ch = 48;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4));
+ multiget();
+}
+
+void DreamGenContext::putundermenu() {
+ STACK_CHECK;
+ di = (80+40);
+ bx = (60);
+ cl = 48;
+ ch = 48;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4));
+ multiput();
+}
+
+void DreamGenContext::showoutermenu() {
+ STACK_CHECK;
+ al = 40;
+ ah = 0;
+ di = (80+40)-34;
+ bx = (60)-40;
+ ds = data.word(kTempgraphics);
+ showframe();
+ al = 41;
+ ah = 0;
+ di = (80+40)+64-34;
+ bx = (60)-40;
+ ds = data.word(kTempgraphics);
+ showframe();
+ al = 42;
+ ah = 0;
+ di = (80+40)-26;
+ bx = (60)+57-40;
+ ds = data.word(kTempgraphics);
+ showframe();
+ al = 43;
+ ah = 0;
+ di = (80+40)+64-26;
+ bx = (60)+57-40;
+ ds = data.word(kTempgraphics);
+ showframe();
+}
+
+void DreamGenContext::showmenu() {
+ STACK_CHECK;
+ _inc(data.byte(kMenucount));
+ _cmp(data.byte(kMenucount), 37*2);
+ if (!flags.z())
+ goto menuframeok;
+ data.byte(kMenucount) = 0;
+menuframeok:
+ al = data.byte(kMenucount);
+ _shr(al, 1);
+ ah = 0;
+ di = (80+40);
+ bx = (60);
+ ds = data.word(kTempgraphics);
+ showframe();
+}
+
+void DreamGenContext::loadmenu() {
+ STACK_CHECK;
+ dx = 1832;
+ loadintotemp();
+ dx = 1987;
+ loadintotemp2();
+}
+
+void DreamGenContext::viewfolder() {
+ STACK_CHECK;
+ data.byte(kManisoffscreen) = 1;
+ getridofall();
+ loadfolder();
+ data.byte(kFolderpage) = 0;
+ showfolder();
+ worktoscreenm();
+ data.byte(kGetback) = 0;
+folderloop:
+ delpointer();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ bx = 3636;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto folderloop;
+ data.byte(kManisoffscreen) = 0;
+ getridoftemp();
+ getridoftemp2();
+ getridoftemp3();
+ getridoftempcharset();
+ restoreall();
+ redrawmainscrn();
+ worktoscreenm();
+}
+
+void DreamGenContext::nextfolder() {
+ STACK_CHECK;
+ _cmp(data.byte(kFolderpage), 12);
+ if (!flags.z())
+ goto cannextf;
+ blank();
+ return;
+cannextf:
+ _cmp(data.byte(kCommandtype), 201);
+ if (flags.z())
+ goto alreadynextf;
+ data.byte(kCommandtype) = 201;
+ al = 16;
+ commandonly();
+alreadynextf:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notnextf) */;
+ _cmp(ax, 1);
+ if (flags.z())
+ goto donextf;
+ return;
+donextf:
+ _inc(data.byte(kFolderpage));
+ folderhints();
+ delpointer();
+ showfolder();
+ data.word(kMousebutton) = 0;
+ bx = 3636;
+ checkcoords();
+ worktoscreenm();
+}
+
+void DreamGenContext::folderhints() {
+ STACK_CHECK;
+ _cmp(data.byte(kFolderpage), 5);
+ if (!flags.z())
+ goto notaideadd;
+ _cmp(data.byte(kAidedead), 1);
+ if (flags.z())
+ goto notaideadd;
+ al = 13;
+ getlocation();
+ _cmp(al, 1);
+ if (flags.z())
+ goto notaideadd;
+ al = 13;
+ setlocation();
+ showfolder();
+ al = 30;
+ findtext1();
+ di = 0;
+ bx = 86;
+ dl = 141;
+ ah = 16;
+ printdirect();
+ worktoscreenm();
+ cx = 200;
+ hangonp();
+ return;
+notaideadd:
+ _cmp(data.byte(kFolderpage), 9);
+ if (!flags.z())
+ return /* (notaristoadd) */;
+ al = 7;
+ getlocation();
+ _cmp(al, 1);
+ if (flags.z())
+ return /* (notaristoadd) */;
+ al = 7;
+ setlocation();
+ showfolder();
+ al = 31;
+ findtext1();
+ di = 0;
+ bx = 86;
+ dl = 141;
+ ah = 16;
+ printdirect();
+ worktoscreenm();
+ cx = 200;
+ hangonp();
+}
+
+void DreamGenContext::lastfolder() {
+ STACK_CHECK;
+ _cmp(data.byte(kFolderpage), 0);
+ if (!flags.z())
+ goto canlastf;
+ blank();
+ return;
+canlastf:
+ _cmp(data.byte(kCommandtype), 202);
+ if (flags.z())
+ goto alreadylastf;
+ data.byte(kCommandtype) = 202;
+ al = 17;
+ commandonly();
+alreadylastf:
+ _cmp(data.byte(kFolderpage), 0);
+ if (flags.z())
+ return /* (notlastf) */;
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notlastf) */;
+ _cmp(ax, 1);
+ if (flags.z())
+ goto dolastf;
+ return;
+dolastf:
+ _dec(data.byte(kFolderpage));
+ delpointer();
+ showfolder();
+ data.word(kMousebutton) = 0;
+ bx = 3636;
+ checkcoords();
+ worktoscreenm();
+}
+
+void DreamGenContext::loadfolder() {
+ STACK_CHECK;
+ dx = 2299;
+ loadintotemp();
+ dx = 2312;
+ loadintotemp2();
+ dx = 2325;
+ loadintotemp3();
+ dx = 1883;
+ loadtempcharset();
+ dx = 2195;
+ loadtemptext();
+}
+
+void DreamGenContext::showfolder() {
+ STACK_CHECK;
+ data.byte(kCommandtype) = 255;
+ _cmp(data.byte(kFolderpage), 0);
+ if (flags.z())
+ goto closedfolder;
+ usetempcharset();
+ createpanel2();
+ ds = data.word(kTempgraphics);
+ di = 0;
+ bx = 0;
+ al = 0;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = 143;
+ bx = 0;
+ al = 1;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = 0;
+ bx = 92;
+ al = 2;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = 143;
+ bx = 92;
+ al = 3;
+ ah = 0;
+ showframe();
+ folderexit();
+ _cmp(data.byte(kFolderpage), 1);
+ if (flags.z())
+ goto noleftpage;
+ showleftpage();
+noleftpage:
+ _cmp(data.byte(kFolderpage), 12);
+ if (flags.z())
+ goto norightpage;
+ showrightpage();
+norightpage:
+ usecharset1();
+ undertextline();
+ return;
+closedfolder:
+ createpanel2();
+ ds = data.word(kTempgraphics3);
+ di = 143-28;
+ bx = 0;
+ al = 0;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics3);
+ di = 143-28;
+ bx = 92;
+ al = 1;
+ ah = 0;
+ showframe();
+ folderexit();
+ undertextline();
+}
+
+void DreamGenContext::folderexit() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics2);
+ di = 296;
+ bx = 178;
+ al = 6;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::showleftpage() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics2);
+ di = 0;
+ bx = 12;
+ al = 3;
+ ah = 0;
+ showframe();
+ bx = 12+5;
+ cx = 9;
+leftpageloop:
+ push(cx);
+ push(bx);
+ ds = data.word(kTempgraphics2);
+ di = 0;
+ al = 4;
+ ah = 0;
+ showframe();
+ bx = pop();
+ cx = pop();
+ _add(bx, 16);
+ if (--cx)
+ goto leftpageloop;
+ ds = data.word(kTempgraphics2);
+ di = 0;
+ al = 5;
+ ah = 0;
+ showframe();
+ data.word(kLinespacing) = 8;
+ data.word(kCharshift) = 91;
+ data.byte(kKerning) = 1;
+ bl = data.byte(kFolderpage);
+ _dec(bl);
+ _dec(bl);
+ _add(bl, bl);
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kTextfile1);
+ si = es.word(bx);
+ _add(si, 66*2);
+ di = 2;
+ bx = 48;
+ dl = 140;
+ cx = 2;
+twolotsleft:
+ push(cx);
+contleftpage:
+ printdirect();
+ _add(bx, data.word(kLinespacing));
+ _cmp(al, 0);
+ if (!flags.z())
+ goto contleftpage;
+ cx = pop();
+ if (--cx)
+ goto twolotsleft;
+ data.byte(kKerning) = 0;
+ data.word(kCharshift) = 0;
+ data.word(kLinespacing) = 10;
+ es = data.word(kWorkspace);
+ ds = data.word(kWorkspace);
+ di = (48*320)+2;
+ si = (48*320)+2+130;
+ cx = 120;
+flipfolder:
+ push(cx);
+ push(di);
+ push(si);
+ cx = 65;
+flipfolderline:
+ al = es.byte(di);
+ ah = es.byte(si);
+ es.byte(di) = ah;
+ es.byte(si) = al;
+ _dec(si);
+ _inc(di);
+ if (--cx)
+ goto flipfolderline;
+ si = pop();
+ di = pop();
+ cx = pop();
+ _add(si, 320);
+ _add(di, 320);
+ if (--cx)
+ goto flipfolder;
+}
+
+void DreamGenContext::showrightpage() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics2);
+ di = 143;
+ bx = 12;
+ al = 0;
+ ah = 0;
+ showframe();
+ bx = 12+37;
+ cx = 7;
+rightpageloop:
+ push(cx);
+ push(bx);
+ ds = data.word(kTempgraphics2);
+ di = 143;
+ al = 1;
+ ah = 0;
+ showframe();
+ bx = pop();
+ cx = pop();
+ _add(bx, 16);
+ if (--cx)
+ goto rightpageloop;
+ ds = data.word(kTempgraphics2);
+ di = 143;
+ al = 2;
+ ah = 0;
+ showframe();
+ data.word(kLinespacing) = 8;
+ data.byte(kKerning) = 1;
+ bl = data.byte(kFolderpage);
+ _dec(bl);
+ _add(bl, bl);
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kTextfile1);
+ si = es.word(bx);
+ _add(si, 66*2);
+ di = 152;
+ bx = 48;
+ dl = 140;
+ cx = 2;
+twolotsright:
+ push(cx);
+contrightpage:
+ printdirect();
+ _add(bx, data.word(kLinespacing));
+ _cmp(al, 0);
+ if (!flags.z())
+ goto contrightpage;
+ cx = pop();
+ if (--cx)
+ goto twolotsright;
+ data.byte(kKerning) = 0;
+ data.word(kLinespacing) = 10;
+}
+
+void DreamGenContext::entersymbol() {
+ STACK_CHECK;
+ data.byte(kManisoffscreen) = 1;
+ getridofreels();
+ dx = 2338;
+ loadintotemp();
+ data.byte(kSymboltopx) = 24;
+ data.byte(kSymboltopdir) = 0;
+ data.byte(kSymbolbotx) = 24;
+ data.byte(kSymbolbotdir) = 0;
+ redrawmainscrn();
+ showsymbol();
+ undertextline();
+ worktoscreenm();
+ data.byte(kGetback) = 0;
+symbolloop:
+ delpointer();
+ updatesymboltop();
+ updatesymbolbot();
+ showsymbol();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ dumpsymbol();
+ bx = 3678;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto symbolloop;
+ _cmp(data.byte(kSymbolbotnum), 3);
+ if (!flags.z())
+ goto symbolwrong;
+ _cmp(data.byte(kSymboltopnum), 5);
+ if (!flags.z())
+ goto symbolwrong;
+ al = 43;
+ removesetobject();
+ al = 46;
+ placesetobject();
+ ah = data.byte(kRoomnum);
+ _add(ah, 12);
+ al = 0;
+ turnanypathon();
+ data.byte(kManisoffscreen) = 0;
+ redrawmainscrn();
+ getridoftemp();
+ restorereels();
+ worktoscreenm();
+ al = 13;
+ playchannel1();
+ return;
+symbolwrong:
+ al = 46;
+ removesetobject();
+ al = 43;
+ placesetobject();
+ ah = data.byte(kRoomnum);
+ _add(ah, 12);
+ al = 0;
+ turnanypathoff();
+ data.byte(kManisoffscreen) = 0;
+ redrawmainscrn();
+ getridoftemp();
+ restorereels();
+ worktoscreenm();
+}
+
+void DreamGenContext::quitsymbol() {
+ STACK_CHECK;
+ _cmp(data.byte(kSymboltopx), 24);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kSymbolbotx), 24);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 222);
+ if (flags.z())
+ goto alreadyqs;
+ data.byte(kCommandtype) = 222;
+ al = 18;
+ commandonly();
+alreadyqs:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notqs) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto doqs;
+ return;
+doqs:
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::settopleft() {
+ STACK_CHECK;
+ _cmp(data.byte(kSymboltopdir), 0);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 210);
+ if (flags.z())
+ goto alreadytopl;
+ data.byte(kCommandtype) = 210;
+ al = 19;
+ commandonly();
+alreadytopl:
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ return /* (notopleft) */;
+ data.byte(kSymboltopdir) = -1;
+}
+
+void DreamGenContext::settopright() {
+ STACK_CHECK;
+ _cmp(data.byte(kSymboltopdir), 0);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 211);
+ if (flags.z())
+ goto alreadytopr;
+ data.byte(kCommandtype) = 211;
+ al = 20;
+ commandonly();
+alreadytopr:
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ return /* (notopright) */;
+ data.byte(kSymboltopdir) = 1;
+}
+
+void DreamGenContext::setbotleft() {
+ STACK_CHECK;
+ _cmp(data.byte(kSymbolbotdir), 0);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 212);
+ if (flags.z())
+ goto alreadybotl;
+ data.byte(kCommandtype) = 212;
+ al = 21;
+ commandonly();
+alreadybotl:
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ return /* (nobotleft) */;
+ data.byte(kSymbolbotdir) = -1;
+}
+
+void DreamGenContext::setbotright() {
+ STACK_CHECK;
+ _cmp(data.byte(kSymbolbotdir), 0);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 213);
+ if (flags.z())
+ goto alreadybotr;
+ data.byte(kCommandtype) = 213;
+ al = 22;
+ commandonly();
+alreadybotr:
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ return /* (nobotright) */;
+ data.byte(kSymbolbotdir) = 1;
+}
+
+void DreamGenContext::dumpsymbol() {
+ STACK_CHECK;
+ data.byte(kNewtextline) = 0;
+ di = (64);
+ bx = (56)+20;
+ cl = 104;
+ ch = 60;
+ multidump();
+}
+
+void DreamGenContext::showsymbol() {
+ STACK_CHECK;
+ al = 12;
+ ah = 0;
+ di = (64);
+ bx = (56);
+ ds = data.word(kTempgraphics);
+ showframe();
+ al = data.byte(kSymboltopx);
+ ah = 0;
+ di = ax;
+ _add(di, (64)-44);
+ al = data.byte(kSymboltopnum);
+ bx = (56)+20;
+ ds = data.word(kTempgraphics);
+ ah = 32;
+ push(ax);
+ push(di);
+ push(bx);
+ push(ds);
+ showframe();
+ ds = pop();
+ bx = pop();
+ di = pop();
+ ax = pop();
+ nextsymbol();
+ _add(di, 49);
+ push(ax);
+ push(di);
+ push(bx);
+ push(ds);
+ showframe();
+ ds = pop();
+ bx = pop();
+ di = pop();
+ ax = pop();
+ nextsymbol();
+ _add(di, 49);
+ showframe();
+ al = data.byte(kSymbolbotx);
+ ah = 0;
+ di = ax;
+ _add(di, (64)-44);
+ al = data.byte(kSymbolbotnum);
+ _add(al, 6);
+ bx = (56)+49;
+ ds = data.word(kTempgraphics);
+ ah = 32;
+ push(ax);
+ push(di);
+ push(bx);
+ push(ds);
+ showframe();
+ ds = pop();
+ bx = pop();
+ di = pop();
+ ax = pop();
+ nextsymbol();
+ _add(di, 49);
+ push(ax);
+ push(di);
+ push(bx);
+ push(ds);
+ showframe();
+ ds = pop();
+ bx = pop();
+ di = pop();
+ ax = pop();
+ nextsymbol();
+ _add(di, 49);
+ showframe();
+}
+
+void DreamGenContext::nextsymbol() {
+ STACK_CHECK;
+ _inc(al);
+ _cmp(al, 6);
+ if (flags.z())
+ goto topwrap;
+ _cmp(al, 12);
+ if (flags.z())
+ goto botwrap;
+ return;
+topwrap:
+ al = 0;
+ return;
+botwrap:
+ al = 6;
+}
+
+void DreamGenContext::updatesymboltop() {
+ STACK_CHECK;
+ _cmp(data.byte(kSymboltopdir), 0);
+ if (flags.z())
+ return /* (topfinished) */;
+ _cmp(data.byte(kSymboltopdir), -1);
+ if (flags.z())
+ goto backwards;
+ _inc(data.byte(kSymboltopx));
+ _cmp(data.byte(kSymboltopx), 49);
+ if (!flags.z())
+ goto notwrapfor;
+ data.byte(kSymboltopx) = 0;
+ _dec(data.byte(kSymboltopnum));
+ _cmp(data.byte(kSymboltopnum), -1);
+ if (!flags.z())
+ return /* (topfinished) */;
+ data.byte(kSymboltopnum) = 5;
+ return;
+notwrapfor:
+ _cmp(data.byte(kSymboltopx), 24);
+ if (!flags.z())
+ return /* (topfinished) */;
+ data.byte(kSymboltopdir) = 0;
+ return;
+backwards:
+ _dec(data.byte(kSymboltopx));
+ _cmp(data.byte(kSymboltopx), -1);
+ if (!flags.z())
+ goto notwrapback;
+ data.byte(kSymboltopx) = 48;
+ _inc(data.byte(kSymboltopnum));
+ _cmp(data.byte(kSymboltopnum), 6);
+ if (!flags.z())
+ return /* (topfinished) */;
+ data.byte(kSymboltopnum) = 0;
+ return;
+notwrapback:
+ _cmp(data.byte(kSymboltopx), 24);
+ if (!flags.z())
+ return /* (topfinished) */;
+ data.byte(kSymboltopdir) = 0;
+}
+
+void DreamGenContext::updatesymbolbot() {
+ STACK_CHECK;
+ _cmp(data.byte(kSymbolbotdir), 0);
+ if (flags.z())
+ return /* (botfinished) */;
+ _cmp(data.byte(kSymbolbotdir), -1);
+ if (flags.z())
+ goto backwardsbot;
+ _inc(data.byte(kSymbolbotx));
+ _cmp(data.byte(kSymbolbotx), 49);
+ if (!flags.z())
+ goto notwrapforb;
+ data.byte(kSymbolbotx) = 0;
+ _dec(data.byte(kSymbolbotnum));
+ _cmp(data.byte(kSymbolbotnum), -1);
+ if (!flags.z())
+ return /* (botfinished) */;
+ data.byte(kSymbolbotnum) = 5;
+ return;
+notwrapforb:
+ _cmp(data.byte(kSymbolbotx), 24);
+ if (!flags.z())
+ return /* (botfinished) */;
+ data.byte(kSymbolbotdir) = 0;
+ return;
+backwardsbot:
+ _dec(data.byte(kSymbolbotx));
+ _cmp(data.byte(kSymbolbotx), -1);
+ if (!flags.z())
+ goto notwrapbackb;
+ data.byte(kSymbolbotx) = 48;
+ _inc(data.byte(kSymbolbotnum));
+ _cmp(data.byte(kSymbolbotnum), 6);
+ if (!flags.z())
+ return /* (botfinished) */;
+ data.byte(kSymbolbotnum) = 0;
+ return;
+notwrapbackb:
+ _cmp(data.byte(kSymbolbotx), 24);
+ if (!flags.z())
+ return /* (botfinished) */;
+ data.byte(kSymbolbotdir) = 0;
+}
+
+void DreamGenContext::dumpsymbox() {
+ STACK_CHECK;
+ _cmp(data.word(kDumpx), -1);
+ if (flags.z())
+ return /* (nodumpsym) */;
+ di = data.word(kDumpx);
+ bx = data.word(kDumpy);
+ cl = 30;
+ ch = 77;
+ multidump();
+ data.word(kDumpx) = -1;
+}
+
+void DreamGenContext::usediary() {
+ STACK_CHECK;
+ getridofreels();
+ dx = 2039;
+ loadintotemp();
+ dx = 2208;
+ loadtemptext();
+ dx = 1883;
+ loadtempcharset();
+ createpanel();
+ showicon();
+ showdiary();
+ undertextline();
+ showdiarypage();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+ data.byte(kGetback) = 0;
+diaryloop:
+ delpointer();
+ readmouse();
+ showdiarykeys();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumpdiarykeys();
+ dumptextline();
+ bx = 3740;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto diaryloop;
+ getridoftemp();
+ getridoftemptext();
+ getridoftempcharset();
+ restorereels();
+ data.byte(kManisoffscreen) = 0;
+ redrawmainscrn();
+ worktoscreenm();
+}
+
+void DreamGenContext::showdiary() {
+ STACK_CHECK;
+ al = 1;
+ ah = 0;
+ di = (68+24);
+ bx = (48+12)+37;
+ ds = data.word(kTempgraphics);
+ showframe();
+ al = 2;
+ ah = 0;
+ di = (68+24)+176;
+ bx = (48+12)+108;
+ ds = data.word(kTempgraphics);
+ showframe();
+}
+
+void DreamGenContext::showdiarykeys() {
+ STACK_CHECK;
+ _cmp(data.byte(kPresscount), 0);
+ if (flags.z())
+ return /* (nokeyatall) */;
+ _dec(data.byte(kPresscount));
+ _cmp(data.byte(kPresscount), 0);
+ if (flags.z())
+ return /* (nokeyatall) */;
+ _cmp(data.byte(kPressed), 'N');
+ if (!flags.z())
+ goto nokeyn;
+ al = 3;
+ _cmp(data.byte(kPresscount), 1);
+ if (flags.z())
+ goto gotkeyn;
+ al = 4;
+gotkeyn:
+ ah = 0;
+ di = (68+24)+94;
+ bx = (48+12)+97;
+ ds = data.word(kTempgraphics);
+ showframe();
+ _cmp(data.byte(kPresscount), 1);
+ if (!flags.z())
+ return /* (notshown) */;
+ showdiarypage();
+ return;
+nokeyn:
+ al = 5;
+ _cmp(data.byte(kPresscount), 1);
+ if (flags.z())
+ goto gotkeyp;
+ al = 6;
+gotkeyp:
+ ah = 0;
+ di = (68+24)+151;
+ bx = (48+12)+71;
+ ds = data.word(kTempgraphics);
+ showframe();
+ _cmp(data.byte(kPresscount), 1);
+ if (!flags.z())
+ return /* (notshowp) */;
+ showdiarypage();
+}
+
+void DreamGenContext::dumpdiarykeys() {
+ STACK_CHECK;
+ _cmp(data.byte(kPresscount), 1);
+ if (!flags.z())
+ goto notdumpdiary;
+ _cmp(data.byte(kSartaindead), 1);
+ if (flags.z())
+ goto notsartadd;
+ _cmp(data.byte(kDiarypage), 5);
+ if (!flags.z())
+ goto notsartadd;
+ _cmp(data.byte(kDiarypage), 5);
+ if (!flags.z())
+ goto notsartadd;
+ al = 6;
+ getlocation();
+ _cmp(al, 1);
+ if (flags.z())
+ goto notsartadd;
+ al = 6;
+ setlocation();
+ delpointer();
+ al = 12;
+ findtext1();
+ di = 70;
+ bx = 106;
+ dl = 241;
+ ah = 16;
+ printdirect();
+ worktoscreenm();
+ cx = 200;
+ hangonp();
+ createpanel();
+ showicon();
+ showdiary();
+ showdiarypage();
+ worktoscreenm();
+ showpointer();
+ return;
+notsartadd:
+ di = (68+24)+48;
+ bx = (48+12)+15;
+ cl = 200;
+ ch = 16;
+ multidump();
+notdumpdiary:
+ di = (68+24)+94;
+ bx = (48+12)+97;
+ cl = 16;
+ ch = 16;
+ multidump();
+ di = (68+24)+151;
+ bx = (48+12)+71;
+ cl = 16;
+ ch = 16;
+ multidump();
+}
+
+void DreamGenContext::diarykeyp() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 214);
+ if (flags.z())
+ goto alreadykeyp;
+ data.byte(kCommandtype) = 214;
+ al = 23;
+ commandonly();
+alreadykeyp:
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ return /* (notkeyp) */;
+ ax = data.word(kOldbutton);
+ _cmp(ax, data.word(kMousebutton));
+ if (flags.z())
+ return /* (notkeyp) */;
+ _cmp(data.byte(kPresscount), 0);
+ if (!flags.z())
+ return /* (notkeyp) */;
+ al = 16;
+ playchannel1();
+ data.byte(kPresscount) = 12;
+ data.byte(kPressed) = 'P';
+ _dec(data.byte(kDiarypage));
+ _cmp(data.byte(kDiarypage), -1);
+ if (!flags.z())
+ return /* (notkeyp) */;
+ data.byte(kDiarypage) = 11;
+}
+
+void DreamGenContext::diarykeyn() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 213);
+ if (flags.z())
+ goto alreadykeyn;
+ data.byte(kCommandtype) = 213;
+ al = 23;
+ commandonly();
+alreadykeyn:
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ return /* (notkeyn) */;
+ ax = data.word(kOldbutton);
+ _cmp(ax, data.word(kMousebutton));
+ if (flags.z())
+ return /* (notkeyn) */;
+ _cmp(data.byte(kPresscount), 0);
+ if (!flags.z())
+ return /* (notkeyn) */;
+ al = 16;
+ playchannel1();
+ data.byte(kPresscount) = 12;
+ data.byte(kPressed) = 'N';
+ _inc(data.byte(kDiarypage));
+ _cmp(data.byte(kDiarypage), 12);
+ if (!flags.z())
+ return /* (notkeyn) */;
+ data.byte(kDiarypage) = 0;
+}
+
+void DreamGenContext::showdiarypage() {
+ STACK_CHECK;
+ al = 0;
+ ah = 0;
+ di = (68+24);
+ bx = (48+12);
+ ds = data.word(kTempgraphics);
+ showframe();
+ al = data.byte(kDiarypage);
+ findtext1();
+ data.byte(kKerning) = 1;
+ usetempcharset();
+ di = (68+24)+48;
+ bx = (48+12)+16;
+ dl = 240;
+ ah = 16;
+ data.word(kCharshift) = 91+91;
+ printdirect();
+ di = (68+24)+129;
+ bx = (48+12)+16;
+ dl = 240;
+ ah = 16;
+ printdirect();
+ di = (68+24)+48;
+ bx = (48+12)+23;
+ dl = 240;
+ ah = 16;
+ printdirect();
+ data.byte(kKerning) = 0;
+ data.word(kCharshift) = 0;
+ usecharset1();
+}
+
+void DreamGenContext::findtext1() {
+ STACK_CHECK;
+ ah = 0;
+ si = ax;
+ _add(si, si);
+ es = data.word(kTextfile1);
+ ax = es.word(si);
+ _add(ax, (66*2));
+ si = ax;
+}
+
+void DreamGenContext::zoomonoff() {
+ STACK_CHECK;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kPointermode), 2);
+ if (flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 222);
+ if (flags.z())
+ goto alreadyonoff;
+ data.byte(kCommandtype) = 222;
+ al = 39;
+ commandonly();
+alreadyonoff:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nozoomonoff) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto dozoomonoff;
+ return;
+dozoomonoff:
+ al = data.byte(kZoomon);
+ _xor(al, 1);
+ data.byte(kZoomon) = al;
+ createpanel();
+ data.byte(kNewobs) = 0;
+ drawfloor();
+ printsprites();
+ reelsonscreen();
+ showicon();
+ getunderzoom();
+ undertextline();
+ al = 39;
+ commandonly();
+ readmouse();
+ worktoscreenm();
+}
+
+void DreamGenContext::saveload() {
+ STACK_CHECK;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kPointermode), 2);
+ if (flags.z())
+ { blank(); return; };
+ _cmp(data.byte(kCommandtype), 253);
+ if (flags.z())
+ goto alreadyops;
+ data.byte(kCommandtype) = 253;
+ al = 43;
+ commandonly();
+alreadyops:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (noops) */;
+ _and(ax, 1);
+ if (flags.z())
+ return /* (noops) */;
+ dosaveload();
+}
+
+void DreamGenContext::dosaveload() {
+ STACK_CHECK;
+ data.byte(kPointerframe) = 0;
+ data.word(kTextaddressx) = 70;
+ data.word(kTextaddressy) = 182-8;
+ data.byte(kTextlen) = 181;
+ data.byte(kManisoffscreen) = 1;
+ clearwork();
+ createpanel2();
+ undertextline();
+ getridofall();
+ loadsavebox();
+ showopbox();
+ showmainops();
+ worktoscreen();
+ goto donefirstops;
+restartops:
+ showopbox();
+ showmainops();
+ worktoscreenm();
+donefirstops:
+ data.byte(kGetback) = 0;
+waitops:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ goto justret;
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ delpointer();
+ bx = 3782;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto waitops;
+ _cmp(data.byte(kGetback), 2);
+ if (flags.z())
+ goto restartops;
+ data.word(kTextaddressx) = 13;
+ data.word(kTextaddressy) = 182;
+ data.byte(kTextlen) = 240;
+ _cmp(data.byte(kGetback), 4);
+ if (flags.z())
+ goto justret;
+ getridoftemp();
+ restoreall();
+ redrawmainscrn();
+ worktoscreenm();
+ data.byte(kCommandtype) = 200;
+justret:
+ data.byte(kManisoffscreen) = 0;
+}
+
+void DreamGenContext::getbackfromops() {
+ STACK_CHECK;
+ _cmp(data.byte(kMandead), 2);
+ if (flags.z())
+ goto opsblock1;
+ getback1();
+ return;
+opsblock1:
+ blank();
+}
+
+void DreamGenContext::showmainops() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics);
+ di = (60)+10;
+ bx = (52)+10;
+ al = 8;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60)+59;
+ bx = (52)+30;
+ al = 7;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60)+128+4;
+ bx = (52)+12;
+ al = 1;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::showdiscops() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics);
+ di = (60)+128+4;
+ bx = (52)+12;
+ al = 1;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60)+10;
+ bx = (52)+10;
+ al = 9;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60)+59;
+ bx = (52)+30;
+ al = 10;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60)+176+2;
+ bx = (52)+60-4;
+ al = 5;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::loadsavebox() {
+ STACK_CHECK;
+ dx = 1961;
+ loadintotemp();
+}
+
+void DreamGenContext::loadgame() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 246);
+ if (flags.z())
+ goto alreadyload;
+ data.byte(kCommandtype) = 246;
+ al = 41;
+ commandonly();
+alreadyload:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (noload) */;
+ _cmp(ax, 1);
+ if (flags.z())
+ goto doload;
+ return;
+doload:
+ data.byte(kLoadingorsave) = 1;
+ showopbox();
+ showloadops();
+ data.byte(kCurrentslot) = 0;
+ showslots();
+ shownames();
+ data.byte(kPointerframe) = 0;
+ worktoscreenm();
+ namestoold();
+ data.byte(kGetback) = 0;
+loadops:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (quitloaded) */;
+ delpointer();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ bx = 3824;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto loadops;
+ _cmp(data.byte(kGetback), 2);
+ if (flags.z())
+ return /* (quitloaded) */;
+ getridoftemp();
+ dx = data;
+ es = dx;
+ bx = 7979;
+ startloading();
+ loadroomssample();
+ data.byte(kRoomloaded) = 1;
+ data.byte(kNewlocation) = 255;
+ clearsprites();
+ initman();
+ initrain();
+ data.word(kTextaddressx) = 13;
+ data.word(kTextaddressy) = 182;
+ data.byte(kTextlen) = 240;
+ startup();
+ worktoscreen();
+ data.byte(kGetback) = 4;
+}
+
+void DreamGenContext::getbacktoops() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 201);
+ if (flags.z())
+ goto alreadygetops;
+ data.byte(kCommandtype) = 201;
+ al = 42;
+ commandonly();
+alreadygetops:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nogetbackops) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto dogetbackops;
+ return;
+dogetbackops:
+ oldtonames();
+ data.byte(kGetback) = 2;
+}
+
+void DreamGenContext::discops() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 249);
+ if (flags.z())
+ goto alreadydiscops;
+ data.byte(kCommandtype) = 249;
+ al = 43;
+ commandonly();
+alreadydiscops:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (nodiscops) */;
+ _and(ax, 1);
+ if (!flags.z())
+ goto dodiscops;
+ return;
+dodiscops:
+ scanfornames();
+ data.byte(kLoadingorsave) = 2;
+ showopbox();
+ showdiscops();
+ data.byte(kCurrentslot) = 0;
+ worktoscreenm();
+ data.byte(kGetback) = 0;
+discopsloop:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (quitdiscops) */;
+ delpointer();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ bx = 3866;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto discopsloop;
+}
+
+void DreamGenContext::savegame() {
+ STACK_CHECK;
+ _cmp(data.byte(kMandead), 2);
+ if (!flags.z())
+ goto cansaveok;
+ blank();
+ return;
+cansaveok:
+ _cmp(data.byte(kCommandtype), 247);
+ if (flags.z())
+ goto alreadysave;
+ data.byte(kCommandtype) = 247;
+ al = 44;
+ commandonly();
+alreadysave:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (!flags.z())
+ goto dosave;
+ return;
+dosave:
+ data.byte(kLoadingorsave) = 2;
+ showopbox();
+ showsaveops();
+ data.byte(kCurrentslot) = 0;
+ showslots();
+ shownames();
+ worktoscreenm();
+ namestoold();
+ data.word(kBufferin) = 0;
+ data.word(kBufferout) = 0;
+ data.byte(kGetback) = 0;
+saveops:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (quitsavegame) */;
+ delpointer();
+ checkinput();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ bx = 3908;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto saveops;
+}
+
+void DreamGenContext::actualsave() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 222);
+ if (flags.z())
+ goto alreadyactsave;
+ data.byte(kCommandtype) = 222;
+ al = 44;
+ commandonly();
+alreadyactsave:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (flags.z())
+ return /* (noactsave) */;
+ dx = data;
+ ds = dx;
+ si = 8579;
+ al = data.byte(kCurrentslot);
+ ah = 0;
+ cx = 17;
+ _mul(cx);
+ _add(si, ax);
+ _inc(si);
+ _cmp(ds.byte(si), 0);
+ if (flags.z())
+ return /* (noactsave) */;
+ al = data.byte(kLocation);
+ ah = 0;
+ cx = 32;
+ _mul(cx);
+ ds = cs;
+ si = 6187;
+ _add(si, ax);
+ di = 7979;
+ bx = di;
+ es = cs;
+ cx = 16;
+ _movsw(cx, true);
+ al = data.byte(kRoomssample);
+ es.byte(bx+13) = al;
+ al = data.byte(kMapx);
+ es.byte(bx+15) = al;
+ al = data.byte(kMapy);
+ es.byte(bx+16) = al;
+ al = data.byte(kLiftflag);
+ es.byte(bx+20) = al;
+ al = data.byte(kManspath);
+ es.byte(bx+21) = al;
+ al = data.byte(kFacing);
+ es.byte(bx+22) = al;
+ al = 255;
+ es.byte(bx+27) = al;
+ saveposition();
+ getridoftemp();
+ restoreall();
+ data.word(kTextaddressx) = 13;
+ data.word(kTextaddressy) = 182;
+ data.byte(kTextlen) = 240;
+ redrawmainscrn();
+ worktoscreenm();
+ data.byte(kGetback) = 4;
+}
+
+void DreamGenContext::actualload() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 221);
+ if (flags.z())
+ goto alreadyactload;
+ data.byte(kCommandtype) = 221;
+ al = 41;
+ commandonly();
+alreadyactload:
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (notactload) */;
+ _cmp(ax, 1);
+ if (!flags.z())
+ return /* (notactload) */;
+ dx = data;
+ ds = dx;
+ si = 8579;
+ al = data.byte(kCurrentslot);
+ ah = 0;
+ cx = 17;
+ _mul(cx);
+ _add(si, ax);
+ _inc(si);
+ _cmp(ds.byte(si), 0);
+ if (flags.z())
+ return /* (notactload) */;
+ loadposition();
+ data.byte(kGetback) = 1;
+}
+
+void DreamGenContext::selectslot2() {
+ STACK_CHECK;
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ goto noselslot2;
+ data.byte(kLoadingorsave) = 2;
+noselslot2:
+ selectslot();
+}
+
+void DreamGenContext::checkinput() {
+ STACK_CHECK;
+ _cmp(data.byte(kLoadingorsave), 3);
+ if (flags.z())
+ return /* (nokeypress) */;
+ readkey();
+ al = data.byte(kCurrentkey);
+ _cmp(al, 0);
+ if (flags.z())
+ return /* (nokeypress) */;
+ _cmp(al, 13);
+ if (!flags.z())
+ goto notret;
+ data.byte(kLoadingorsave) = 3;
+ goto afterkey;
+notret:
+ _cmp(al, 8);
+ if (!flags.z())
+ goto nodel2;
+ _cmp(data.byte(kCursorpos), 0);
+ if (flags.z())
+ return /* (nokeypress) */;
+ getnamepos();
+ _dec(data.byte(kCursorpos));
+ es.byte(bx) = 0;
+ es.byte(bx+1) = 1;
+ goto afterkey;
+nodel2:
+ _cmp(data.byte(kCursorpos), 14);
+ if (flags.z())
+ return /* (nokeypress) */;
+ getnamepos();
+ _inc(data.byte(kCursorpos));
+ al = data.byte(kCurrentkey);
+ es.byte(bx+1) = al;
+ es.byte(bx+2) = 0;
+ es.byte(bx+3) = 1;
+ goto afterkey;
+ return;
+afterkey:
+ showopbox();
+ shownames();
+ showslots();
+ showsaveops();
+ worktoscreenm();
+}
+
+void DreamGenContext::getnamepos() {
+ STACK_CHECK;
+ al = data.byte(kCurrentslot);
+ ah = 0;
+ cx = 17;
+ _mul(cx);
+ dx = data;
+ es = dx;
+ bx = 8579;
+ _add(bx, ax);
+ al = data.byte(kCursorpos);
+ ah = 0;
+ _add(bx, ax);
+}
+
+void DreamGenContext::showopbox() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics);
+ di = (60);
+ bx = (52);
+ al = 0;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60);
+ bx = (52)+55;
+ al = 4;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::showloadops() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics);
+ di = (60)+128+4;
+ bx = (52)+12;
+ al = 1;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60)+176+2;
+ bx = (52)+60-4;
+ al = 5;
+ ah = 0;
+ showframe();
+ di = (60)+104;
+ bx = (52)+14;
+ al = 55;
+ dl = 101;
+ printmessage();
+}
+
+void DreamGenContext::showsaveops() {
+ STACK_CHECK;
+ ds = data.word(kTempgraphics);
+ di = (60)+128+4;
+ bx = (52)+12;
+ al = 1;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempgraphics);
+ di = (60)+176+2;
+ bx = (52)+60-4;
+ al = 5;
+ ah = 0;
+ showframe();
+ di = (60)+104;
+ bx = (52)+14;
+ al = 54;
+ dl = 101;
+ printmessage();
+}
+
+void DreamGenContext::selectslot() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 244);
+ if (flags.z())
+ goto alreadysel;
+ data.byte(kCommandtype) = 244;
+ al = 45;
+ commandonly();
+alreadysel:
+ ax = data.word(kMousebutton);
+ _cmp(ax, 1);
+ if (!flags.z())
+ return /* (noselslot) */;
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (noselslot) */;
+ _cmp(data.byte(kLoadingorsave), 3);
+ if (!flags.z())
+ goto notnocurs;
+ _dec(data.byte(kLoadingorsave));
+notnocurs:
+ oldtonames();
+ ax = data.word(kMousey);
+ _sub(ax, (52)+4);
+ cl = -1;
+getslotnum:
+ _inc(cl);
+ _sub(ax, 11);
+ if (!flags.c())
+ goto getslotnum;
+ data.byte(kCurrentslot) = cl;
+ delpointer();
+ showopbox();
+ showslots();
+ shownames();
+ _cmp(data.byte(kLoadingorsave), 1);
+ if (flags.z())
+ goto isloadmode;
+ showsaveops();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+ return;
+isloadmode:
+ showloadops();
+ readmouse();
+ showpointer();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::showslots() {
+ STACK_CHECK;
+ di = (60)+7;
+ bx = (52)+8;
+ al = 2;
+ ds = data.word(kTempgraphics);
+ ah = 0;
+ showframe();
+ di = (60)+10;
+ bx = (52)+11;
+ cl = 0;
+slotloop:
+ push(cx);
+ push(di);
+ push(bx);
+ _cmp(cl, data.byte(kCurrentslot));
+ if (!flags.z())
+ goto nomatchslot;
+ al = 3;
+ ds = data.word(kTempgraphics);
+ ah = 0;
+ showframe();
+nomatchslot:
+ bx = pop();
+ di = pop();
+ cx = pop();
+ _add(bx, 10);
+ _inc(cl);
+ _cmp(cl, 7);
+ if (!flags.z())
+ goto slotloop;
+}
+
+void DreamGenContext::shownames() {
+ STACK_CHECK;
+ dx = data;
+ es = dx;
+ si = 8579+1;
+ di = (60)+21;
+ bx = (52)+10;
+ cl = 0;
+shownameloop:
+ push(cx);
+ push(di);
+ push(es);
+ push(bx);
+ push(si);
+ al = 4;
+ _cmp(cl, data.byte(kCurrentslot));
+ if (!flags.z())
+ goto nomatchslot2;
+ _cmp(data.byte(kLoadingorsave), 2);
+ if (!flags.z())
+ goto loadmode;
+ dx = si;
+ cx = 15;
+ _add(si, 15);
+zerostill:
+ _dec(si);
+ _dec(cl);
+ _cmp(es.byte(si), 1);
+ if (!flags.z())
+ goto foundcharacter;
+ goto zerostill;
+foundcharacter:
+ data.byte(kCursorpos) = cl;
+ es.byte(si) = '/';
+ es.byte(si+1) = 0;
+ push(si);
+ si = dx;
+ dl = 200;
+ ah = 0;
+ printdirect();
+ si = pop();
+ es.byte(si) = 0;
+ es.byte(si+1) = 1;
+ goto afterprintname;
+loadmode:
+ al = 0;
+ dl = 200;
+ ah = 0;
+ data.word(kCharshift) = 91;
+ printdirect();
+ data.word(kCharshift) = 0;
+ goto afterprintname;
+nomatchslot2:
+ dl = 200;
+ ah = 0;
+ printdirect();
+afterprintname:
+ si = pop();
+ bx = pop();
+ es = pop();
+ di = pop();
+ cx = pop();
+ _add(si, 17);
+ _add(bx, 10);
+ _inc(cl);
+ _cmp(cl, 7);
+ if (!flags.z())
+ goto shownameloop;
+}
+
+void DreamGenContext::namestoold() {
+ STACK_CHECK;
+ ds = cs;
+ si = 8579;
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5));
+ es = data.word(kBuffers);
+ cx = 17*4;
+ _movsb(cx, true);
+}
+
+void DreamGenContext::oldtonames() {
+ STACK_CHECK;
+ es = cs;
+ di = 8579;
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5));
+ ds = data.word(kBuffers);
+ cx = 17*4;
+ _movsb(cx, true);
+}
+
+void DreamGenContext::saveposition() {
+ STACK_CHECK;
+ makeheader();
+ al = data.byte(kCurrentslot);
+ ah = 0;
+ push(ax);
+ cx = 13;
+ _mul(cx);
+ dx = data;
+ ds = dx;
+ dx = 8698;
+ _add(dx, ax);
+ openforsave();
+ dx = data;
+ ds = dx;
+ dx = 6091;
+ cx = (6187-6091);
+ savefilewrite();
+ dx = data;
+ es = dx;
+ di = 6141;
+ ax = pop();
+ cx = 17;
+ _mul(cx);
+ dx = data;
+ ds = dx;
+ dx = 8579;
+ _add(dx, ax);
+ saveseg();
+ dx = data;
+ ds = dx;
+ dx = 0;
+ saveseg();
+ ds = data.word(kExtras);
+ dx = (0);
+ saveseg();
+ ds = data.word(kBuffers);
+ dx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80));
+ saveseg();
+ dx = data;
+ ds = dx;
+ dx = 7979;
+ saveseg();
+ dx = data;
+ ds = dx;
+ dx = 534;
+ saveseg();
+ closefile();
+}
+
+void DreamGenContext::loadposition() {
+ STACK_CHECK;
+ data.word(kTimecount) = 0;
+ clearchanges();
+ al = data.byte(kCurrentslot);
+ ah = 0;
+ push(ax);
+ cx = 13;
+ _mul(cx);
+ dx = data;
+ ds = dx;
+ dx = 8698;
+ _add(dx, ax);
+ openfilefromc();
+ ds = cs;
+ dx = 6091;
+ cx = (6187-6091);
+ savefileread();
+ es = cs;
+ di = 6141;
+ ax = pop();
+ cx = 17;
+ _mul(cx);
+ dx = data;
+ ds = dx;
+ dx = 8579;
+ _add(dx, ax);
+ loadseg();
+ dx = data;
+ ds = dx;
+ dx = 0;
+ loadseg();
+ ds = data.word(kExtras);
+ dx = (0);
+ loadseg();
+ ds = data.word(kBuffers);
+ dx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80));
+ loadseg();
+ dx = data;
+ ds = dx;
+ dx = 7979;
+ loadseg();
+ ds = cs;
+ dx = 534;
+ loadseg();
+ closefile();
+}
+
+void DreamGenContext::makeheader() {
+ STACK_CHECK;
+ dx = data;
+ es = dx;
+ di = 6141;
+ ax = 17;
+ storeit();
+ ax = (68-0);
+ storeit();
+ ax = (0+2080+30000+(16*114)+((114+2)*2)+18000);
+ storeit();
+ ax = (250)*4;
+ storeit();
+ ax = 48;
+ storeit();
+ ax = (991-534);
+ storeit();
+}
+
+void DreamGenContext::storeit() {
+ STACK_CHECK;
+ _cmp(ax, 0);
+ if (!flags.z())
+ goto isntblank;
+ _inc(ax);
+isntblank:
+ _stosw();
+}
+
+void DreamGenContext::findlen() {
+ STACK_CHECK;
+ _dec(bx);
+ _add(bx, ax);
+nextone:
+ _cmp(cl, ds.byte(bx));
+ if (!flags.z())
+ return /* (foundlen) */;
+ _dec(bx);
+ _dec(ax);
+ _cmp(ax, 0);
+ if (!flags.z())
+ goto nextone;
+}
+
+void DreamGenContext::scanfornames() {
+ STACK_CHECK;
+ dx = data;
+ es = dx;
+ di = 8579;
+ dx = data;
+ ds = dx;
+ dx = 8698;
+ cx = 7;
+scanloop:
+ push(es);
+ push(ds);
+ push(di);
+ push(dx);
+ push(cx);
+ openfilefromc();
+ if (flags.c())
+ goto notexist;
+ cx = pop();
+ _inc(ch);
+ push(cx);
+ push(di);
+ push(es);
+ dx = data;
+ ds = dx;
+ dx = 6091;
+ cx = (6187-6091);
+ savefileread();
+ dx = data;
+ es = dx;
+ di = 6141;
+ ds = pop();
+ dx = pop();
+ loadseg();
+ bx = data.word(kHandle);
+ closefile();
+notexist:
+ cx = pop();
+ dx = pop();
+ di = pop();
+ ds = pop();
+ es = pop();
+ _add(dx, 13);
+ _add(di, 17);
+ _dec(cl);
+ if (!flags.z())
+ goto scanloop;
+ al = ch;
+}
+
+void DreamGenContext::decide() {
+ STACK_CHECK;
+ setmode();
+ loadpalfromiff();
+ clearpalette();
+ data.byte(kPointermode) = 0;
+ data.word(kWatchingtime) = 0;
+ data.byte(kPointerframe) = 0;
+ data.word(kTextaddressx) = 70;
+ data.word(kTextaddressy) = 182-8;
+ data.byte(kTextlen) = 181;
+ data.byte(kManisoffscreen) = 1;
+ loadsavebox();
+ showdecisions();
+ worktoscreen();
+ fadescreenup();
+ data.byte(kGetback) = 0;
+waitdecide:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (flags.z())
+ goto _tmp1;
+ return;
+_tmp1:
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ delpointer();
+ bx = 5057;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto waitdecide;
+ _cmp(data.byte(kGetback), 4);
+ if (flags.z())
+ goto hasloadedroom;
+ getridoftemp();
+hasloadedroom:
+ data.word(kTextaddressx) = 13;
+ data.word(kTextaddressy) = 182;
+ data.byte(kTextlen) = 240;
+}
+
+void DreamGenContext::showdecisions() {
+ STACK_CHECK;
+ createpanel2();
+ showopbox();
+ ds = data.word(kTempgraphics);
+ di = (60)+17;
+ bx = (52)+13;
+ al = 6;
+ ah = 0;
+ showframe();
+ undertextline();
+}
+
+void DreamGenContext::newgame() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 251);
+ if (flags.z())
+ goto alreadynewgame;
+ data.byte(kCommandtype) = 251;
+ al = 47;
+ commandonly();
+alreadynewgame:
+ ax = data.word(kMousebutton);
+ _cmp(ax, 1);
+ if (!flags.z())
+ return /* (nonewgame) */;
+ data.byte(kGetback) = 3;
+}
+
+void DreamGenContext::doload() {
+ STACK_CHECK;
+ data.byte(kLoadingorsave) = 1;
+ showopbox();
+ showloadops();
+ data.byte(kCurrentslot) = 0;
+ showslots();
+ shownames();
+ data.byte(kPointerframe) = 0;
+ worktoscreenm();
+ namestoold();
+ data.byte(kGetback) = 0;
+loadops:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (quitloaded) */;
+ delpointer();
+ readmouse();
+ showpointer();
+ vsync();
+ dumppointer();
+ dumptextline();
+ bx = 3824;
+ checkcoords();
+ _cmp(data.byte(kGetback), 0);
+ if (flags.z())
+ goto loadops;
+ _cmp(data.byte(kGetback), 2);
+ if (flags.z())
+ return /* (quitloaded) */;
+ getridoftemp();
+ dx = data;
+ es = dx;
+ bx = 7979;
+ startloading();
+ loadroomssample();
+ data.byte(kRoomloaded) = 1;
+ data.byte(kNewlocation) = 255;
+ clearsprites();
+ initman();
+ initrain();
+ data.word(kTextaddressx) = 13;
+ data.word(kTextaddressy) = 182;
+ data.byte(kTextlen) = 240;
+ startup();
+ worktoscreen();
+ data.byte(kGetback) = 4;
+}
+
+void DreamGenContext::loadold() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 252);
+ if (flags.z())
+ goto alreadyloadold;
+ data.byte(kCommandtype) = 252;
+ al = 48;
+ commandonly();
+alreadyloadold:
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (flags.z())
+ return /* (noloadold) */;
+ doload();
+ _cmp(data.byte(kGetback), 4);
+ if (flags.z())
+ return /* (noloadold) */;
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (noloadold) */;
+ showdecisions();
+ worktoscreenm();
+ data.byte(kGetback) = 0;
+}
+
+void DreamGenContext::createname() {
+ STACK_CHECK;
+ push(ax);
+ di = 5105;
+ cs.byte(di+0) = dl;
+ cs.byte(di+3) = cl;
+ al = dh;
+ ah = '0'-1;
+findten:
+ _inc(ah);
+ _sub(al, 10);
+ if (!flags.c())
+ goto findten;
+ cs.byte(di+1) = ah;
+ _add(al, 10+'0');
+ cs.byte(di+2) = al;
+ ax = pop();
+ cl = '0'-1;
+thousandsc:
+ _inc(cl);
+ _sub(ax, 1000);
+ if (!flags.c())
+ goto thousandsc;
+ _add(ax, 1000);
+ cs.byte(di+4) = cl;
+ cl = '0'-1;
+hundredsc:
+ _inc(cl);
+ _sub(ax, 100);
+ if (!flags.c())
+ goto hundredsc;
+ _add(ax, 100);
+ cs.byte(di+5) = cl;
+ cl = '0'-1;
+tensc:
+ _inc(cl);
+ _sub(ax, 10);
+ if (!flags.c())
+ goto tensc;
+ _add(ax, 10);
+ cs.byte(di+6) = cl;
+ _add(al, '0');
+ cs.byte(di+7) = al;
+}
+
+void DreamGenContext::trysoundalloc() {
+ STACK_CHECK;
+ _cmp(data.byte(kNeedsoundbuff), 1);
+ if (flags.z())
+ return /* (gotsoundbuff) */;
+ _inc(data.byte(kSoundtimes));
+ bx = (16384+2048)/16;
+ allocatemem();
+ data.word(kSoundbuffer) = ax;
+ push(ax);
+ al = ah;
+ cl = 4;
+ _shr(al, cl);
+ data.byte(kSoundbufferpage) = al;
+ ax = pop();
+ cl = 4;
+ _shl(ax, cl);
+ data.word(kSoundbufferad) = ax;
+ _cmp(ax, 0x0b7ff);
+ if (!flags.c())
+ goto soundfail;
+ es = data.word(kSoundbuffer);
+ di = 0;
+ cx = 16384/2;
+ ax = 0x7f7f;
+ _stosw(cx, true);
+ data.byte(kNeedsoundbuff) = 1;
+ return;
+soundfail:
+ es = data.word(kSoundbuffer);
+ deallocatemem();
+}
+
+void DreamGenContext::playchannel0() {
+ STACK_CHECK;
+ _cmp(data.byte(kSoundint), 255);
+ if (flags.z())
+ return /* (dontbother4) */;
+ push(es);
+ push(ds);
+ push(bx);
+ push(cx);
+ push(di);
+ push(si);
+ data.byte(kCh0playing) = al;
+ es = data.word(kSounddata);
+ _cmp(al, 12);
+ if (flags.c())
+ goto notsecondbank;
+ es = data.word(kSounddata2);
+ _sub(al, 12);
+notsecondbank:
+ data.byte(kCh0repeat) = ah;
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ _add(ax, ax);
+ _add(bx, ax);
+ al = es.byte(bx);
+ ah = 0;
+ data.word(kCh0emmpage) = ax;
+ ax = es.word(bx+1);
+ data.word(kCh0offset) = ax;
+ ax = es.word(bx+3);
+ data.word(kCh0blockstocopy) = ax;
+ _cmp(data.byte(kCh0repeat), 0);
+ if (flags.z())
+ goto nosetloop;
+ ax = data.word(kCh0emmpage);
+ data.word(kCh0oldemmpage) = ax;
+ ax = data.word(kCh0offset);
+ data.word(kCh0oldoffset) = ax;
+ ax = data.word(kCh0blockstocopy);
+ data.word(kCh0oldblockstocopy) = ax;
+nosetloop:
+ si = pop();
+ di = pop();
+ cx = pop();
+ bx = pop();
+ ds = pop();
+ es = pop();
+}
+
+void DreamGenContext::playchannel1() {
+ STACK_CHECK;
+ _cmp(data.byte(kSoundint), 255);
+ if (flags.z())
+ return /* (dontbother5) */;
+ _cmp(data.byte(kCh1playing), 7);
+ if (flags.z())
+ return /* (dontbother5) */;
+ push(es);
+ push(ds);
+ push(bx);
+ push(cx);
+ push(di);
+ push(si);
+ data.byte(kCh1playing) = al;
+ es = data.word(kSounddata);
+ _cmp(al, 12);
+ if (flags.c())
+ goto notsecondbank1;
+ es = data.word(kSounddata2);
+ _sub(al, 12);
+notsecondbank1:
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ _add(ax, ax);
+ _add(bx, ax);
+ al = es.byte(bx);
+ ah = 0;
+ data.word(kCh1emmpage) = ax;
+ ax = es.word(bx+1);
+ data.word(kCh1offset) = ax;
+ ax = es.word(bx+3);
+ data.word(kCh1blockstocopy) = ax;
+ si = pop();
+ di = pop();
+ cx = pop();
+ bx = pop();
+ ds = pop();
+ es = pop();
+}
+
+void DreamGenContext::makenextblock() {
+ STACK_CHECK;
+ volumeadjust();
+ loopchannel0();
+ _cmp(data.word(kCh1blockstocopy), 0);
+ if (flags.z())
+ goto mightbeonlych0;
+ _cmp(data.word(kCh0blockstocopy), 0);
+ if (flags.z())
+ goto mightbeonlych1;
+ _dec(data.word(kCh0blockstocopy));
+ _dec(data.word(kCh1blockstocopy));
+ bothchannels();
+ return;
+mightbeonlych1:
+ data.byte(kCh0playing) = 255;
+ _cmp(data.word(kCh1blockstocopy), 0);
+ if (flags.z())
+ return /* (notch1only) */;
+ _dec(data.word(kCh1blockstocopy));
+ channel1only();
+ return;
+mightbeonlych0:
+ data.byte(kCh1playing) = 255;
+ _cmp(data.word(kCh0blockstocopy), 0);
+ if (flags.z())
+ goto notch0only;
+ _dec(data.word(kCh0blockstocopy));
+ channel0only();
+ return;
+notch0only:
+ es = data.word(kSoundbuffer);
+ di = data.word(kSoundbufferwrite);
+ cx = 1024;
+ ax = 0x7f7f;
+ _stosw(cx, true);
+ _and(di, 16384-1);
+ data.word(kSoundbufferwrite) = di;
+}
+
+void DreamGenContext::volumeadjust() {
+ STACK_CHECK;
+ al = data.byte(kVolumedirection);
+ _cmp(al, 0);
+ if (flags.z())
+ return /* (volok) */;
+ al = data.byte(kVolume);
+ _cmp(al, data.byte(kVolumeto));
+ if (flags.z())
+ goto volfinish;
+ _add(data.byte(kVolumecount), 64);
+ if (!flags.z())
+ return /* (volok) */;
+ al = data.byte(kVolume);
+ _add(al, data.byte(kVolumedirection));
+ data.byte(kVolume) = al;
+ return;
+volfinish:
+ data.byte(kVolumedirection) = 0;
+}
+
+void DreamGenContext::loopchannel0() {
+ STACK_CHECK;
+ _cmp(data.word(kCh0blockstocopy), 0);
+ if (!flags.z())
+ return /* (notloop) */;
+ _cmp(data.byte(kCh0repeat), 0);
+ if (flags.z())
+ return /* (notloop) */;
+ _cmp(data.byte(kCh0repeat), 255);
+ if (flags.z())
+ goto endlessloop;
+ _dec(data.byte(kCh0repeat));
+endlessloop:
+ ax = data.word(kCh0oldemmpage);
+ data.word(kCh0emmpage) = ax;
+ ax = data.word(kCh0oldoffset);
+ data.word(kCh0offset) = ax;
+ ax = data.word(kCh0blockstocopy);
+ _add(ax, data.word(kCh0oldblockstocopy));
+ data.word(kCh0blockstocopy) = ax;
+}
+
+void DreamGenContext::cancelch0() {
+ STACK_CHECK;
+ data.byte(kCh0repeat) = 0;
+ data.word(kCh0blockstocopy) = 0;
+ data.byte(kCh0playing) = 255;
+}
+
+void DreamGenContext::cancelch1() {
+ STACK_CHECK;
+ data.word(kCh1blockstocopy) = 0;
+ data.byte(kCh1playing) = 255;
+}
+
+void DreamGenContext::channel0tran() {
+ STACK_CHECK;
+ _cmp(data.byte(kVolume), 0);
+ if (!flags.z())
+ goto lowvolumetran;
+ cx = 1024;
+ _movsw(cx, true);
+ return;
+lowvolumetran:
+ cx = 1024;
+ bh = data.byte(kVolume);
+ bl = 0;
+ _add(bx, 16384-256);
+volloop:
+ _lodsw();
+ bl = al;
+ al = es.byte(bx);
+ bl = ah;
+ ah = es.byte(bx);
+ _stosw();
+ if (--cx)
+ goto volloop;
+}
+
+void DreamGenContext::domix() {
+ STACK_CHECK;
+ _cmp(data.byte(kVolume), 0);
+ if (!flags.z())
+ goto lowvolumemix;
+slow:
+ _lodsb();
+ ah = ds.byte(bx);
+ _inc(bx);
+ _cmp(al, dh);
+ if (!flags.c())
+ goto toplot;
+ _cmp(ah, dh);
+ if (!flags.c())
+ goto nodistort;
+ _add(al, ah);
+ if (flags.s())
+ goto botok;
+ _xor(al, al);
+ _stosb();
+ if (--cx)
+ goto slow;
+ return /* (doneit) */;
+botok:
+ _xor(al, dh);
+ _stosb();
+ if (--cx)
+ goto slow;
+ return /* (doneit) */;
+toplot:
+ _cmp(ah, dh);
+ if (flags.c())
+ goto nodistort;
+ _add(al, ah);
+ if (!flags.s())
+ goto topok;
+ al = dl;
+ _stosb();
+ if (--cx)
+ goto slow;
+ return /* (doneit) */;
+topok:
+ _xor(al, dh);
+ _stosb();
+ if (--cx)
+ goto slow;
+ return /* (doneit) */;
+nodistort:
+ _add(al, ah);
+ _xor(al, dh);
+ _stosb();
+ if (--cx)
+ goto slow;
+ return /* (doneit) */;
+lowvolumemix:
+ _lodsb();
+ push(bx);
+ bh = data.byte(kVolume);
+ _add(bh, 63);
+ bl = al;
+ al = es.byte(bx);
+ bx = pop();
+ ah = ds.byte(bx);
+ _inc(bx);
+ _cmp(al, dh);
+ if (!flags.c())
+ goto toplotv;
+ _cmp(ah, dh);
+ if (!flags.c())
+ goto nodistortv;
+ _add(al, ah);
+ if (flags.s())
+ goto botokv;
+ _xor(al, al);
+ _stosb();
+ if (--cx)
+ goto lowvolumemix;
+ return /* (doneit) */;
+botokv:
+ _xor(al, dh);
+ _stosb();
+ if (--cx)
+ goto lowvolumemix;
+ return /* (doneit) */;
+toplotv:
+ _cmp(ah, dh);
+ if (flags.c())
+ goto nodistortv;
+ _add(al, ah);
+ if (!flags.s())
+ goto topokv;
+ al = dl;
+ _stosb();
+ if (--cx)
+ goto lowvolumemix;
+ return /* (doneit) */;
+topokv:
+ _xor(al, dh);
+ _stosb();
+ if (--cx)
+ goto lowvolumemix;
+ return /* (doneit) */;
+nodistortv:
+ _add(al, ah);
+ _xor(al, dh);
+ _stosb();
+ if (--cx)
+ goto lowvolumemix;
+}
+
+void DreamGenContext::entrytexts() {
+ STACK_CHECK;
+ _cmp(data.byte(kLocation), 21);
+ if (!flags.z())
+ goto notloc15;
+ al = 28;
+ cx = 60;
+ dx = 11;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+ return;
+notloc15:
+ _cmp(data.byte(kLocation), 30);
+ if (!flags.z())
+ goto notloc43;
+ al = 27;
+ cx = 60;
+ dx = 11;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+ return;
+notloc43:
+ _cmp(data.byte(kLocation), 23);
+ if (!flags.z())
+ goto notloc23;
+ al = 29;
+ cx = 60;
+ dx = 11;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+ return;
+notloc23:
+ _cmp(data.byte(kLocation), 31);
+ if (!flags.z())
+ goto notloc44;
+ al = 30;
+ cx = 60;
+ dx = 11;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+ return;
+notloc44:
+ _cmp(data.byte(kLocation), 20);
+ if (!flags.z())
+ goto notsarters2;
+ al = 31;
+ cx = 60;
+ dx = 11;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+ return;
+notsarters2:
+ _cmp(data.byte(kLocation), 24);
+ if (!flags.z())
+ goto notedenlob;
+ al = 32;
+ cx = 60;
+ dx = 3;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+ return;
+notedenlob:
+ _cmp(data.byte(kLocation), 34);
+ if (!flags.z())
+ return /* (noteden2) */;
+ al = 33;
+ cx = 60;
+ dx = 3;
+ bl = 68;
+ bh = 64;
+ setuptimeduse();
+}
+
+void DreamGenContext::entryanims() {
+ STACK_CHECK;
+ data.word(kReeltowatch) = -1;
+ data.byte(kWatchmode) = -1;
+ _cmp(data.byte(kLocation), 33);
+ if (!flags.z())
+ goto notinthebeach;
+ switchryanoff();
+ data.word(kWatchingtime) = 76*2;
+ data.word(kReeltowatch) = 0;
+ data.word(kEndwatchreel) = 76;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ return;
+notinthebeach:
+ _cmp(data.byte(kLocation), 44);
+ if (!flags.z())
+ goto notsparkys;
+ al = 8;
+ resetlocation();
+ data.word(kWatchingtime) = 50*2;
+ data.word(kReeltowatch) = 247;
+ data.word(kEndwatchreel) = 297;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ switchryanoff();
+ return;
+notsparkys:
+ _cmp(data.byte(kLocation), 22);
+ if (!flags.z())
+ goto notinthelift;
+ data.word(kWatchingtime) = 31*2;
+ data.word(kReeltowatch) = 0;
+ data.word(kEndwatchreel) = 30;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ switchryanoff();
+ return;
+notinthelift:
+ _cmp(data.byte(kLocation), 26);
+ if (!flags.z())
+ goto notunderchurch;
+ data.byte(kSymboltopnum) = 2;
+ data.byte(kSymbolbotnum) = 1;
+ return;
+notunderchurch:
+ _cmp(data.byte(kLocation), 45);
+ if (!flags.z())
+ goto notenterdream;
+ data.byte(kKeeperflag) = 0;
+ data.word(kWatchingtime) = 296;
+ data.word(kReeltowatch) = 45;
+ data.word(kEndwatchreel) = 198;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ switchryanoff();
+ return;
+notenterdream:
+ _cmp(data.byte(kReallocation), 46);
+ if (!flags.z())
+ goto notcrystal;
+ _cmp(data.byte(kSartaindead), 1);
+ if (!flags.z())
+ goto notcrystal;
+ al = 0;
+ removefreeobject();
+ return;
+notcrystal:
+ _cmp(data.byte(kLocation), 9);
+ if (!flags.z())
+ goto nottopchurch;
+ al = 2;
+ checkifpathison();
+ if (flags.z())
+ goto nottopchurch;
+ _cmp(data.byte(kAidedead), 0);
+ if (flags.z())
+ goto nottopchurch;
+ al = 3;
+ checkifpathison();
+ if (!flags.z())
+ goto makedoorsopen;
+ al = 2;
+ turnpathon();
+makedoorsopen:
+ al = 4;
+ removesetobject();
+ al = 5;
+ placesetobject();
+ return;
+nottopchurch:
+ _cmp(data.byte(kLocation), 47);
+ if (!flags.z())
+ goto notdreamcentre;
+ al = 4;
+ placesetobject();
+ al = 5;
+ placesetobject();
+ return;
+notdreamcentre:
+ _cmp(data.byte(kLocation), 38);
+ if (!flags.z())
+ goto notcarpark;
+ data.word(kWatchingtime) = 57*2;
+ data.word(kReeltowatch) = 4;
+ data.word(kEndwatchreel) = 57;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ switchryanoff();
+ return;
+notcarpark:
+ _cmp(data.byte(kLocation), 32);
+ if (!flags.z())
+ goto notalley;
+ data.word(kWatchingtime) = 66*2;
+ data.word(kReeltowatch) = 0;
+ data.word(kEndwatchreel) = 66;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ switchryanoff();
+ return;
+notalley:
+ _cmp(data.byte(kLocation), 24);
+ if (!flags.z())
+ return /* (notedensagain) */;
+ al = 2;
+ ah = data.byte(kRoomnum);
+ _dec(ah);
+ turnanypathon();
+}
+
+void DreamGenContext::initialinv() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 24);
+ if (flags.z())
+ goto isedens;
+ return;
+isedens:
+ al = 11;
+ ah = 5;
+ pickupob();
+ al = 12;
+ ah = 6;
+ pickupob();
+ al = 13;
+ ah = 7;
+ pickupob();
+ al = 14;
+ ah = 8;
+ pickupob();
+ al = 18;
+ al = 18;
+ ah = 0;
+ pickupob();
+ al = 19;
+ ah = 1;
+ pickupob();
+ al = 20;
+ ah = 9;
+ pickupob();
+ al = 16;
+ ah = 2;
+ pickupob();
+ data.byte(kWatchmode) = 1;
+ data.word(kReeltohold) = 0;
+ data.word(kEndofholdreel) = 6;
+ data.byte(kWatchspeed) = 1;
+ data.byte(kSpeedcount) = 1;
+ switchryanoff();
+}
+
+void DreamGenContext::pickupob() {
+ STACK_CHECK;
+ data.byte(kLastinvpos) = ah;
+ data.byte(kObjecttype) = 2;
+ data.byte(kItemframe) = al;
+ data.byte(kCommand) = al;
+ getanyad();
+ transfertoex();
+}
+
+void DreamGenContext::checkforemm() {
+ STACK_CHECK;
+}
+
+void DreamGenContext::checkbasemem() {
+ STACK_CHECK;
+ bx = data.word(kHowmuchalloc);
+ _cmp(bx, 0x9360);
+ if (!flags.c())
+ return /* (enoughmem) */;
+ data.byte(kGameerror) = 5;
+ { quickquit(); return; };
+}
+
+void DreamGenContext::allocatebuffers() {
+ STACK_CHECK;
+ bx = (0+2080+30000+(16*114)+((114+2)*2)+18000)/16;
+ allocatemem();
+ data.word(kExtras) = ax;
+ trysoundalloc();
+ bx = (0+(66*60))/16;
+ allocatemem();
+ data.word(kMapdata) = ax;
+ trysoundalloc();
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+991-534+68-0)/16;
+ allocatemem();
+ data.word(kBuffers) = ax;
+ trysoundalloc();
+ bx = (16*80)/16;
+ allocatemem();
+ data.word(kFreedat) = ax;
+ trysoundalloc();
+ bx = (64*128)/16;
+ allocatemem();
+ data.word(kSetdat) = ax;
+ trysoundalloc();
+ bx = (22*8*20*8)/16;
+ allocatemem();
+ data.word(kMapstore) = ax;
+ allocatework();
+ bx = 2048/16;
+ allocatemem();
+ data.word(kSounddata) = ax;
+ bx = 2048/16;
+ allocatemem();
+ data.word(kSounddata2) = ax;
+}
+
+void DreamGenContext::clearbuffers() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ cx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+991-534+68-0)/2;
+ ax = 0;
+ di = 0;
+ _stosw(cx, true);
+ es = data.word(kExtras);
+ cx = (0+2080+30000+(16*114)+((114+2)*2)+18000)/2;
+ ax = 0x0ffff;
+ di = 0;
+ _stosw(cx, true);
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64));
+ ds = cs;
+ si = 534;
+ cx = (991-534);
+ _movsb(cx, true);
+ es = data.word(kBuffers);
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+991-534);
+ ds = cs;
+ si = 0;
+ cx = (68-0);
+ _movsb(cx, true);
+ clearchanges();
+}
+
+void DreamGenContext::clearchanges() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ cx = (250)*2;
+ ax = 0x0ffff;
+ di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80));
+ _stosw(cx, true);
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64));
+ es = cs;
+ di = 534;
+ cx = (991-534);
+ _movsb(cx, true);
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+991-534);
+ es = cs;
+ di = 0;
+ cx = (68-0);
+ _movsb(cx, true);
+ data.byte(kExpos) = 0;
+ data.word(kExframepos) = 0;
+ data.word(kExtextpos) = 0;
+ es = data.word(kExtras);
+ cx = (0+2080+30000+(16*114)+((114+2)*2)+18000)/2;
+ ax = 0x0ffff;
+ di = 0;
+ _stosw(cx, true);
+ es = cs;
+ di = 8011;
+ al = 1;
+ _stosb(2);
+ al = 0;
+ _stosb();
+ al = 1;
+ _stosb();
+ ax = 0;
+ cx = 6;
+ _stosw(cx, true);
+}
+
+void DreamGenContext::clearbeforeload() {
+ STACK_CHECK;
+ _cmp(data.byte(kRoomloaded), 1);
+ if (!flags.z())
+ return /* (noclear) */;
+ clearreels();
+ clearrest();
+ data.byte(kRoomloaded) = 0;
+}
+
+void DreamGenContext::clearreels() {
+ STACK_CHECK;
+ es = data.word(kReel1);
+ deallocatemem();
+ es = data.word(kReel2);
+ deallocatemem();
+ es = data.word(kReel3);
+ deallocatemem();
+}
+
+void DreamGenContext::clearrest() {
+ STACK_CHECK;
+ es = data.word(kMapdata);
+ cx = (66*60)/2;
+ ax = 0;
+ di = (0);
+ _stosw(cx, true);
+ es = data.word(kBackdrop);
+ deallocatemem();
+ es = data.word(kSetframes);
+ deallocatemem();
+ es = data.word(kReels);
+ deallocatemem();
+ es = data.word(kPeople);
+ deallocatemem();
+ es = data.word(kSetdesc);
+ deallocatemem();
+ es = data.word(kBlockdesc);
+ deallocatemem();
+ es = data.word(kRoomdesc);
+ deallocatemem();
+ es = data.word(kFreeframes);
+ deallocatemem();
+ es = data.word(kFreedesc);
+ deallocatemem();
+}
+
+void DreamGenContext::parseblaster() {
+ STACK_CHECK;
+lookattail:
+ al = es.byte(bx);
+ _cmp(al, 0);
+ if (flags.z())
+ return /* (endtail) */;
+ _cmp(al, 13);
+ if (flags.z())
+ return /* (endtail) */;
+ _cmp(al, 'i');
+ if (flags.z())
+ goto issoundint;
+ _cmp(al, 'I');
+ if (flags.z())
+ goto issoundint;
+ _cmp(al, 'b');
+ if (flags.z())
+ goto isbright;
+ _cmp(al, 'B');
+ if (flags.z())
+ goto isbright;
+ _cmp(al, 'a');
+ if (flags.z())
+ goto isbaseadd;
+ _cmp(al, 'A');
+ if (flags.z())
+ goto isbaseadd;
+ _cmp(al, 'n');
+ if (flags.z())
+ goto isnosound;
+ _cmp(al, 'N');
+ if (flags.z())
+ goto isnosound;
+ _cmp(al, 'd');
+ if (flags.z())
+ goto isdma;
+ _cmp(al, 'D');
+ if (flags.z())
+ goto isdma;
+ _inc(bx);
+ if (--cx)
+ goto lookattail;
+ return;
+issoundint:
+ al = es.byte(bx+1);
+ _sub(al, '0');
+ data.byte(kSoundint) = al;
+ _inc(bx);
+ goto lookattail;
+isdma:
+ al = es.byte(bx+1);
+ _sub(al, '0');
+ data.byte(kSounddmachannel) = al;
+ _inc(bx);
+ goto lookattail;
+isbaseadd:
+ push(cx);
+ al = es.byte(bx+2);
+ _sub(al, '0');
+ ah = 0;
+ cl = 4;
+ _shl(ax, cl);
+ _add(ax, 0x200);
+ data.word(kSoundbaseadd) = ax;
+ cx = pop();
+ _inc(bx);
+ goto lookattail;
+isbright:
+ data.byte(kBrightness) = 1;
+ _inc(bx);
+ goto lookattail;
+isnosound:
+ data.byte(kSoundint) = 255;
+ _inc(bx);
+ goto lookattail;
+}
+
+void DreamGenContext::startup() {
+ STACK_CHECK;
+ data.byte(kCurrentkey) = 0;
+ data.byte(kMainmode) = 0;
+ createpanel();
+ data.byte(kNewobs) = 1;
+ drawfloor();
+ showicon();
+ getunderzoom();
+ spriteupdate();
+ printsprites();
+ undertextline();
+ reelsonscreen();
+ atmospheres();
+}
+
+void DreamGenContext::startup1() {
+ STACK_CHECK;
+ clearpalette();
+ data.byte(kThroughdoor) = 0;
+ data.byte(kCurrentkey) = '0';
+ data.byte(kMainmode) = 0;
+ createpanel();
+ data.byte(kNewobs) = 1;
+ drawfloor();
+ showicon();
+ getunderzoom();
+ spriteupdate();
+ printsprites();
+ undertextline();
+ reelsonscreen();
+ atmospheres();
+ worktoscreen();
+ fadescreenup();
+}
+
+void DreamGenContext::screenupdate() {
+ STACK_CHECK;
+ newplace();
+ mainscreen();
+ animpointer();
+ showpointer();
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ goto iswatchingmode;
+ _cmp(data.byte(kNewlocation), 255);
+ if (!flags.z())
+ return /* (finishearly) */;
+iswatchingmode:
+ vsync();
+ readmouse1();
+ dumppointer();
+ dumptextline();
+ delpointer();
+ autolook();
+ spriteupdate();
+ watchcount();
+ zoom();
+ showpointer();
+ _cmp(data.byte(kWongame), 0);
+ if (!flags.z())
+ return /* (finishearly) */;
+ vsync();
+ readmouse2();
+ dumppointer();
+ dumpzoom();
+ delpointer();
+ deleverything();
+ printsprites();
+ reelsonscreen();
+ afternewroom();
+ showpointer();
+ vsync();
+ readmouse3();
+ dumppointer();
+ dumpmap();
+ dumptimedtext();
+ delpointer();
+ showpointer();
+ vsync();
+ readmouse4();
+ dumppointer();
+ dumpwatch();
+ delpointer();
+}
+
+void DreamGenContext::watchreel() {
+ STACK_CHECK;
+ _cmp(data.word(kReeltowatch), -1);
+ if (flags.z())
+ goto notplayingreel;
+ al = data.byte(kManspath);
+ _cmp(al, data.byte(kFinaldest));
+ if (!flags.z())
+ return /* (waitstopwalk) */;
+ al = data.byte(kTurntoface);
+ _cmp(al, data.byte(kFacing));
+ if (flags.z())
+ goto notwatchpath;
+ return;
+notwatchpath:
+ _dec(data.byte(kSpeedcount));
+ _cmp(data.byte(kSpeedcount), -1);
+ if (!flags.z())
+ goto showwatchreel;
+ al = data.byte(kWatchspeed);
+ data.byte(kSpeedcount) = al;
+ ax = data.word(kReeltowatch);
+ _cmp(ax, data.word(kEndwatchreel));
+ if (!flags.z())
+ goto ismorereel;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ goto showwatchreel;
+ data.word(kReeltowatch) = -1;
+ data.byte(kWatchmode) = -1;
+ _cmp(data.word(kReeltohold), -1);
+ if (flags.z())
+ return /* (nomorereel) */;
+ data.byte(kWatchmode) = 1;
+ goto notplayingreel;
+ismorereel:
+ _inc(data.word(kReeltowatch));
+showwatchreel:
+ ax = data.word(kReeltowatch);
+ data.word(kReelpointer) = ax;
+ plotreel();
+ ax = data.word(kReelpointer);
+ data.word(kReeltowatch) = ax;
+ checkforshake();
+ return;
+notplayingreel:
+ _cmp(data.byte(kWatchmode), 1);
+ if (!flags.z())
+ goto notholdingreel;
+ ax = data.word(kReeltohold);
+ data.word(kReelpointer) = ax;
+ plotreel();
+ return;
+notholdingreel:
+ _cmp(data.byte(kWatchmode), 2);
+ if (!flags.z())
+ return /* (notreleasehold) */;
+ _dec(data.byte(kSpeedcount));
+ _cmp(data.byte(kSpeedcount), -1);
+ if (!flags.z())
+ goto notlastspeed2;
+ al = data.byte(kWatchspeed);
+ data.byte(kSpeedcount) = al;
+ _inc(data.word(kReeltohold));
+notlastspeed2:
+ ax = data.word(kReeltohold);
+ _cmp(ax, data.word(kEndofholdreel));
+ if (!flags.z())
+ goto ismorereel2;
+ data.word(kReeltohold) = -1;
+ data.byte(kWatchmode) = -1;
+ al = data.byte(kDestafterhold);
+ data.byte(kDestination) = al;
+ data.byte(kFinaldest) = al;
+ autosetwalk();
+ return;
+ismorereel2:
+ ax = data.word(kReeltohold);
+ data.word(kReelpointer) = ax;
+ plotreel();
+}
+
+void DreamGenContext::checkforshake() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 26);
+ if (!flags.z())
+ return /* (notstartshake) */;
+ _cmp(ax, 104);
+ if (!flags.z())
+ return /* (notstartshake) */;
+ data.byte(kShakecounter) = -1;
+}
+
+void DreamGenContext::watchcount() {
+ STACK_CHECK;
+ _cmp(data.byte(kWatchon), 0);
+ if (flags.z())
+ return /* (nowatchworn) */;
+ _inc(data.byte(kTimercount));
+ _cmp(data.byte(kTimercount), 9);
+ if (flags.z())
+ goto flashdots;
+ _cmp(data.byte(kTimercount), 18);
+ if (flags.z())
+ goto uptime;
+ return;
+flashdots:
+ ax = 91*3+21;
+ di = 268+4;
+ bx = 21;
+ ds = data.word(kCharset1);
+ showframe();
+ goto finishwatch;
+uptime:
+ data.byte(kTimercount) = 0;
+ _add(data.byte(kSecondcount), 1);
+ _cmp(data.byte(kSecondcount), 60);
+ if (!flags.z())
+ goto finishtime;
+ data.byte(kSecondcount) = 0;
+ _inc(data.byte(kMinutecount));
+ _cmp(data.byte(kMinutecount), 60);
+ if (!flags.z())
+ goto finishtime;
+ data.byte(kMinutecount) = 0;
+ _inc(data.byte(kHourcount));
+ _cmp(data.byte(kHourcount), 24);
+ if (!flags.z())
+ goto finishtime;
+ data.byte(kHourcount) = 0;
+finishtime:
+ showtime();
+finishwatch:
+ data.byte(kWatchdump) = 1;
+}
+
+void DreamGenContext::showtime() {
+ STACK_CHECK;
+ _cmp(data.byte(kWatchon), 0);
+ if (flags.z())
+ return /* (nowatch) */;
+ al = data.byte(kSecondcount);
+ cl = 0;
+ twodigitnum();
+ push(ax);
+ al = ah;
+ ah = 0;
+ _add(ax, 91*3+10);
+ ds = data.word(kCharset1);
+ di = 282+5;
+ bx = 21;
+ showframe();
+ ax = pop();
+ ah = 0;
+ _add(ax, 91*3+10);
+ ds = data.word(kCharset1);
+ di = 282+9;
+ bx = 21;
+ showframe();
+ al = data.byte(kMinutecount);
+ cl = 0;
+ twodigitnum();
+ push(ax);
+ al = ah;
+ ah = 0;
+ _add(ax, 91*3);
+ ds = data.word(kCharset1);
+ di = 270+5;
+ bx = 21;
+ showframe();
+ ax = pop();
+ ah = 0;
+ _add(ax, 91*3);
+ ds = data.word(kCharset1);
+ di = 270+11;
+ bx = 21;
+ showframe();
+ al = data.byte(kHourcount);
+ cl = 0;
+ twodigitnum();
+ push(ax);
+ al = ah;
+ ah = 0;
+ _add(ax, 91*3);
+ ds = data.word(kCharset1);
+ di = 256+5;
+ bx = 21;
+ showframe();
+ ax = pop();
+ ah = 0;
+ _add(ax, 91*3);
+ ds = data.word(kCharset1);
+ di = 256+11;
+ bx = 21;
+ showframe();
+ ax = 91*3+20;
+ ds = data.word(kCharset1);
+ di = 267+5;
+ bx = 21;
+ showframe();
+}
+
+void DreamGenContext::dumpwatch() {
+ STACK_CHECK;
+ _cmp(data.byte(kWatchdump), 1);
+ if (!flags.z())
+ return /* (nodumpwatch) */;
+ di = 256;
+ bx = 21;
+ cl = 40;
+ ch = 12;
+ multidump();
+ data.byte(kWatchdump) = 0;
+}
+
+void DreamGenContext::showbyte() {
+ STACK_CHECK;
+ dl = al;
+ _shr(dl, 1);
+ _shr(dl, 1);
+ _shr(dl, 1);
+ _shr(dl, 1);
+ onedigit();
+ es.byte(di) = dl;
+ dl = al;
+ _and(dl, 15);
+ onedigit();
+ es.byte(di+1) = dl;
+ _add(di, 3);
+}
+
+void DreamGenContext::onedigit() {
+ STACK_CHECK;
+ _cmp(dl, 10);
+ if (!flags.c())
+ goto morethan10;
+ _add(dl, '0');
+ return;
+morethan10:
+ _sub(dl, 10);
+ _add(dl, 'A');
+}
+
+void DreamGenContext::twodigitnum() {
+ STACK_CHECK;
+ ah = cl;
+ _dec(ah);
+numloop1:
+ _inc(ah);
+ _sub(al, 10);
+ if (!flags.c())
+ goto numloop1;
+ _add(al, 10);
+ _add(al, cl);
+}
+
+void DreamGenContext::showword() {
+ STACK_CHECK;
+ ch = 0;
+ bx = 10000;
+ cl = 47;
+word1:
+ _inc(cl);
+ _sub(ax, bx);
+ if (!flags.c())
+ goto word1;
+ _add(ax, bx);
+ convnum();
+ cs.byte(di) = cl;
+ bx = 1000;
+ cl = 47;
+word2:
+ _inc(cl);
+ _sub(ax, bx);
+ if (!flags.c())
+ goto word2;
+ _add(ax, bx);
+ convnum();
+ cs.byte(di+1) = cl;
+ bx = 100;
+ cl = 47;
+word3:
+ _inc(cl);
+ _sub(ax, bx);
+ if (!flags.c())
+ goto word3;
+ _add(ax, bx);
+ convnum();
+ cs.byte(di+2) = cl;
+ bx = 10;
+ cl = 47;
+word4:
+ _inc(cl);
+ _sub(ax, bx);
+ if (!flags.c())
+ goto word4;
+ _add(ax, bx);
+ convnum();
+ cs.byte(di+3) = cl;
+ _add(al, 48);
+ cl = al;
+ convnum();
+ cs.byte(di+4) = cl;
+}
+
+void DreamGenContext::convnum() {
+ STACK_CHECK;
+ _cmp(ch, 0);
+ if (!flags.z())
+ return /* (noconvnum) */;
+ _cmp(cl, '0');
+ if (!flags.z())
+ goto notzeronum;
+ cl = 32;
+ return /* (noconvnum) */;
+notzeronum:
+ ch = 1;
+}
+
+void DreamGenContext::walkandexamine() {
+ STACK_CHECK;
+ finishedwalking();
+ if (!flags.z())
+ return /* (noobselect) */;
+ al = data.byte(kWalkexamtype);
+ data.byte(kCommandtype) = al;
+ al = data.byte(kWalkexamnum);
+ data.byte(kCommand) = al;
+ data.byte(kWalkandexam) = 0;
+ _cmp(data.byte(kCommandtype), 5);
+ if (flags.z())
+ return /* (noobselect) */;
+ examineob();
+ return;
+wantstowalk:
+ setwalk();
+ data.byte(kReasseschanges) = 1;
+ return;
+diff:
+ data.byte(kCommand) = al;
+ data.byte(kCommandtype) = ah;
+ _cmp(data.byte(kLinepointer), 254);
+ if (!flags.z())
+ goto middleofwalk;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ goto middleofwalk;
+ al = data.byte(kFacing);
+ _cmp(al, data.byte(kTurntoface));
+ if (!flags.z())
+ goto middleofwalk;
+ _cmp(data.byte(kCommandtype), 3);
+ if (!flags.z())
+ goto notblock;
+ bl = data.byte(kManspath);
+ _cmp(bl, data.byte(kPointerspath));
+ if (!flags.z())
+ goto dontcheck;
+ cl = data.byte(kRyanx);
+ _add(cl, 12);
+ ch = data.byte(kRyany);
+ _add(ch, 12);
+ checkone();
+ _cmp(cl, 2);
+ if (flags.c())
+ goto isblock;
+dontcheck:
+ getflagunderp();
+ _cmp(data.byte(kLastflag), 2);
+ if (flags.c())
+ goto isblock;
+ _cmp(data.byte(kLastflag), 128);
+ if (!flags.c())
+ goto isblock;
+ goto toofaraway;
+notblock:
+ bl = data.byte(kManspath);
+ _cmp(bl, data.byte(kPointerspath));
+ if (!flags.z())
+ goto toofaraway;
+ _cmp(data.byte(kCommandtype), 3);
+ if (flags.z())
+ goto isblock;
+ _cmp(data.byte(kCommandtype), 5);
+ if (flags.z())
+ goto isaperson;
+ examineobtext();
+ return;
+middleofwalk:
+ blocknametext();
+ return;
+isblock:
+ blocknametext();
+ return;
+isaperson:
+ personnametext();
+ return;
+toofaraway:
+ walktotext();
+}
+
+void DreamGenContext::mainscreen() {
+ STACK_CHECK;
+ data.byte(kInmaparea) = 0;
+ bx = 5122;
+ _cmp(data.byte(kWatchon), 1);
+ if (flags.z())
+ goto checkmain;
+ bx = 5184;
+checkmain:
+ checkcoords();
+ _cmp(data.byte(kWalkandexam), 0);
+ if (flags.z())
+ return /* (finishmain) */;
+ walkandexamine();
+}
+
+void DreamGenContext::madmanrun() {
+ STACK_CHECK;
+ _cmp(data.byte(kLocation), 14);
+ if (!flags.z())
+ { identifyob(); return; };
+ _cmp(data.byte(kMapx), 22);
+ if (!flags.z())
+ { identifyob(); return; };
+ _cmp(data.byte(kPointermode), 2);
+ if (!flags.z())
+ { identifyob(); return; };
+ _cmp(data.byte(kMadmanflag), 0);
+ if (!flags.z())
+ { identifyob(); return; };
+ _cmp(data.byte(kCommandtype), 211);
+ if (flags.z())
+ goto alreadyrun;
+ data.byte(kCommandtype) = 211;
+ al = 52;
+ commandonly();
+alreadyrun:
+ _cmp(data.word(kMousebutton), 1);
+ if (!flags.z())
+ return /* (norun) */;
+ ax = data.word(kMousebutton);
+ _cmp(ax, data.word(kOldbutton));
+ if (flags.z())
+ return /* (norun) */;
+ data.byte(kLastweapon) = 8;
+}
+
+void DreamGenContext::checkcoords() {
+ STACK_CHECK;
+ _cmp(data.byte(kNewlocation), 255);
+ if (flags.z())
+ goto loop048;
+ return;
+loop048:
+ ax = cs.word(bx);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ return /* (nonefound) */;
+ push(bx);
+ _cmp(data.word(kMousex), ax);
+ if (flags.l())
+ goto over045;
+ ax = cs.word(bx+2);
+ _cmp(data.word(kMousex), ax);
+ if (!flags.l())
+ goto over045;
+ ax = cs.word(bx+4);
+ _cmp(data.word(kMousey), ax);
+ if (flags.l())
+ goto over045;
+ ax = cs.word(bx+6);
+ _cmp(data.word(kMousey), ax);
+ if (!flags.l())
+ goto over045;
+ ax = cs.word(bx+8);
+ __dispatch_call(ax);
+ ax = pop();
+ return;
+over045:
+ bx = pop();
+ _add(bx, 10);
+ goto loop048;
+}
+
+void DreamGenContext::identifyob() {
+ STACK_CHECK;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ { blank(); return; };
+ ax = data.word(kMousex);
+ _sub(ax, data.word(kMapadx));
+ _cmp(ax, 22*8);
+ if (flags.c())
+ goto notover1;
+ blank();
+ return;
+notover1:
+ bx = data.word(kMousey);
+ _sub(bx, data.word(kMapady));
+ _cmp(bx, 20*8);
+ if (flags.c())
+ goto notover2;
+ blank();
+ return;
+notover2:
+ data.byte(kInmaparea) = 1;
+ ah = bl;
+ push(ax);
+ findpathofpoint();
+ data.byte(kPointerspath) = dl;
+ ax = pop();
+ push(ax);
+ findfirstpath();
+ data.byte(kPointerfirstpath) = al;
+ ax = pop();
+ checkifex();
+ if (!flags.z())
+ return /* (finishidentify) */;
+ checkiffree();
+ if (!flags.z())
+ return /* (finishidentify) */;
+ checkifperson();
+ if (!flags.z())
+ return /* (finishidentify) */;
+ checkifset();
+ if (!flags.z())
+ return /* (finishidentify) */;
+ ax = data.word(kMousex);
+ _sub(ax, data.word(kMapadx));
+ cl = al;
+ ax = data.word(kMousey);
+ _sub(ax, data.word(kMapady));
+ ch = al;
+ checkone();
+ _cmp(al, 0);
+ if (flags.z())
+ goto nothingund;
+ _cmp(data.byte(kMandead), 1);
+ if (flags.z())
+ goto nothingund;
+ ah = 3;
+ obname();
+ return;
+nothingund:
+ blank();
+}
+
+void DreamGenContext::checkifperson() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5));
+ cx = 12;
+identifyreel:
+ push(cx);
+ _cmp(es.byte(bx+4), 255);
+ if (flags.z())
+ goto notareelid;
+ push(es);
+ push(bx);
+ push(ax);
+ ax = es.word(bx+0);
+ data.word(kReelpointer) = ax;
+ getreelstart();
+ _cmp(es.word(si+2), 0x0ffff);
+ if (!flags.z())
+ goto notblankpers;
+ _add(si, 5);
+notblankpers:
+ cx = es.word(si+2);
+ ax = es.word(si+0);
+ push(cx);
+ getreelframeax();
+ cx = pop();
+ _add(cl, es.byte(bx+4));
+ _add(ch, es.byte(bx+5));
+ dx = cx;
+ _add(dl, es.byte(bx+0));
+ _add(dh, es.byte(bx+1));
+ ax = pop();
+ bx = pop();
+ es = pop();
+ _cmp(al, cl);
+ if (flags.c())
+ goto notareelid;
+ _cmp(ah, ch);
+ if (flags.c())
+ goto notareelid;
+ _cmp(al, dl);
+ if (!flags.c())
+ goto notareelid;
+ _cmp(ah, dh);
+ if (!flags.c())
+ goto notareelid;
+ cx = pop();
+ ax = es.word(bx+2);
+ data.word(kPersondata) = ax;
+ al = es.byte(bx+4);
+ ah = 5;
+ obname();
+ al = 0;
+ _cmp(al, 1);
+ return;
+notareelid:
+ cx = pop();
+ _add(bx, 5);
+ _dec(cx);
+ if (!flags.z())
+ goto identifyreel;
+}
+
+void DreamGenContext::checkifset() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32))+(127*5);
+ cx = 127;
+identifyset:
+ _cmp(es.byte(bx+4), 255);
+ if (flags.z())
+ goto notasetid;
+ _cmp(al, es.byte(bx));
+ if (flags.c())
+ goto notasetid;
+ _cmp(al, es.byte(bx+2));
+ if (!flags.c())
+ goto notasetid;
+ _cmp(ah, es.byte(bx+1));
+ if (flags.c())
+ goto notasetid;
+ _cmp(ah, es.byte(bx+3));
+ if (!flags.c())
+ goto notasetid;
+ pixelcheckset();
+ if (flags.z())
+ goto notasetid;
+ isitdescribed();
+ if (flags.z())
+ goto notasetid;
+ al = es.byte(bx+4);
+ ah = 1;
+ obname();
+ al = 0;
+ _cmp(al, 1);
+ return;
+notasetid:
+ _sub(bx, 5);
+ _dec(cx);
+ _cmp(cx, -1);
+ if (!flags.z())
+ goto identifyset;
+}
+
+void DreamGenContext::checkifex() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5))+(99*5);
+ cx = 99;
+identifyex:
+ _cmp(es.byte(bx+4), 255);
+ if (flags.z())
+ goto notanexid;
+ _cmp(al, es.byte(bx));
+ if (flags.c())
+ goto notanexid;
+ _cmp(al, es.byte(bx+2));
+ if (!flags.c())
+ goto notanexid;
+ _cmp(ah, es.byte(bx+1));
+ if (flags.c())
+ goto notanexid;
+ _cmp(ah, es.byte(bx+3));
+ if (!flags.c())
+ goto notanexid;
+ al = es.byte(bx+4);
+ ah = 4;
+ obname();
+ al = 1;
+ _cmp(al, 0);
+ return;
+notanexid:
+ _sub(bx, 5);
+ _dec(cx);
+ _cmp(cx, -1);
+ if (!flags.z())
+ goto identifyex;
+}
+
+void DreamGenContext::checkiffree() {
+ STACK_CHECK;
+ es = data.word(kBuffers);
+ bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5))+(79*5);
+ cx = 79;
+identifyfree:
+ _cmp(es.byte(bx+4), 255);
+ if (flags.z())
+ goto notafreeid;
+ _cmp(al, es.byte(bx));
+ if (flags.c())
+ goto notafreeid;
+ _cmp(al, es.byte(bx+2));
+ if (!flags.c())
+ goto notafreeid;
+ _cmp(ah, es.byte(bx+1));
+ if (flags.c())
+ goto notafreeid;
+ _cmp(ah, es.byte(bx+3));
+ if (!flags.c())
+ goto notafreeid;
+ al = es.byte(bx+4);
+ ah = 2;
+ obname();
+ al = 0;
+ _cmp(al, 1);
+ return;
+notafreeid:
+ _sub(bx, 5);
+ _dec(cx);
+ _cmp(cx, -1);
+ if (!flags.z())
+ goto identifyfree;
+}
+
+void DreamGenContext::isitdescribed() {
+ STACK_CHECK;
+ push(ax);
+ push(cx);
+ push(es);
+ push(bx);
+ al = es.byte(bx+4);
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ es = data.word(kSetdesc);
+ _add(bx, (0));
+ ax = es.word(bx);
+ _add(ax, (0+(130*2)));
+ bx = ax;
+ dl = es.byte(bx);
+ bx = pop();
+ es = pop();
+ cx = pop();
+ ax = pop();
+ _cmp(dl, 0);
+}
+
+void DreamGenContext::findpathofpoint() {
+ STACK_CHECK;
+ push(ax);
+ bx = (0);
+ es = data.word(kReels);
+ al = data.byte(kRoomnum);
+ ah = 0;
+ cx = 144;
+ _mul(cx);
+ _add(bx, ax);
+ cx = pop();
+ dl = 0;
+pathloop:
+ al = es.byte(bx+6);
+ _cmp(al, 255);
+ if (!flags.z())
+ goto flunkedit;
+ ax = es.word(bx+2);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ goto flunkedit;
+ _cmp(cl, al);
+ if (flags.c())
+ goto flunkedit;
+ _cmp(ch, ah);
+ if (flags.c())
+ goto flunkedit;
+ ax = es.word(bx+4);
+ _cmp(cl, al);
+ if (!flags.c())
+ goto flunkedit;
+ _cmp(ch, ah);
+ if (!flags.c())
+ goto flunkedit;
+ return /* (gotvalidpath) */;
+flunkedit:
+ _add(bx, 8);
+ _inc(dl);
+ _cmp(dl, 12);
+ if (!flags.z())
+ goto pathloop;
+ dl = 255;
+}
+
+void DreamGenContext::findfirstpath() {
+ STACK_CHECK;
+ push(ax);
+ bx = (0);
+ es = data.word(kReels);
+ al = data.byte(kRoomnum);
+ ah = 0;
+ cx = 144;
+ _mul(cx);
+ _add(bx, ax);
+ cx = pop();
+ dl = 0;
+fpathloop:
+ ax = es.word(bx+2);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ goto nofirst;
+ _cmp(cl, al);
+ if (flags.c())
+ goto nofirst;
+ _cmp(ch, ah);
+ if (flags.c())
+ goto nofirst;
+ ax = es.word(bx+4);
+ _cmp(cl, al);
+ if (!flags.c())
+ goto nofirst;
+ _cmp(ch, ah);
+ if (!flags.c())
+ goto nofirst;
+ goto gotfirst;
+nofirst:
+ _add(bx, 8);
+ _inc(dl);
+ _cmp(dl, 12);
+ if (!flags.z())
+ goto fpathloop;
+ al = 0;
+ return;
+gotfirst:
+ al = es.byte(bx+6);
+}
+
+void DreamGenContext::turnpathon() {
+ STACK_CHECK;
+ push(ax);
+ push(ax);
+ cl = 255;
+ ch = data.byte(kRoomnum);
+ _add(ch, 100);
+ findormake();
+ ax = pop();
+ getroomspaths();
+ ax = pop();
+ _cmp(al, 255);
+ if (flags.z())
+ return /* (nopathon) */;
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = 255;
+ es.byte(bx+6) = al;
+}
+
+void DreamGenContext::turnpathoff() {
+ STACK_CHECK;
+ push(ax);
+ push(ax);
+ cl = 0;
+ ch = data.byte(kRoomnum);
+ _add(ch, 100);
+ findormake();
+ ax = pop();
+ getroomspaths();
+ ax = pop();
+ _cmp(al, 255);
+ if (flags.z())
+ return /* (nopathoff) */;
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = 0;
+ es.byte(bx+6) = al;
+}
+
+void DreamGenContext::turnanypathon() {
+ STACK_CHECK;
+ push(ax);
+ push(ax);
+ cl = 255;
+ ch = ah;
+ _add(ch, 100);
+ findormake();
+ ax = pop();
+ al = ah;
+ ah = 0;
+ cx = 144;
+ _mul(cx);
+ es = data.word(kReels);
+ bx = (0);
+ _add(bx, ax);
+ ax = pop();
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = 255;
+ es.byte(bx+6) = al;
+}
+
+void DreamGenContext::turnanypathoff() {
+ STACK_CHECK;
+ push(ax);
+ push(ax);
+ cl = 0;
+ ch = ah;
+ _add(ch, 100);
+ findormake();
+ ax = pop();
+ al = ah;
+ ah = 0;
+ cx = 144;
+ _mul(cx);
+ es = data.word(kReels);
+ bx = (0);
+ _add(bx, ax);
+ ax = pop();
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = 0;
+ es.byte(bx+6) = al;
+}
+
+void DreamGenContext::checkifpathison() {
+ STACK_CHECK;
+ push(ax);
+ getroomspaths();
+ ax = pop();
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = es.byte(bx+6);
+ _cmp(al, 255);
+}
+
+void DreamGenContext::afternewroom() {
+ STACK_CHECK;
+ _cmp(data.byte(kNowinnewroom), 0);
+ if (flags.z())
+ return /* (notnew) */;
+ data.word(kTimecount) = 0;
+ createpanel();
+ data.byte(kCommandtype) = 0;
+ findroominloc();
+ _cmp(data.byte(kRyanon), 1);
+ if (flags.z())
+ goto ryansoff;
+ al = data.byte(kRyanx);
+ _add(al, 12);
+ ah = data.byte(kRyany);
+ _add(ah, 12);
+ findpathofpoint();
+ data.byte(kManspath) = dl;
+ findxyfrompath();
+ data.byte(kResetmanxy) = 1;
+ryansoff:
+ data.byte(kNewobs) = 1;
+ drawfloor();
+ data.word(kLookcounter) = 160;
+ data.byte(kNowinnewroom) = 0;
+ showicon();
+ spriteupdate();
+ printsprites();
+ undertextline();
+ reelsonscreen();
+ mainscreen();
+ getunderzoom();
+ zoom();
+ worktoscreenm();
+ walkintoroom();
+ reminders();
+ atmospheres();
+}
+
+void DreamGenContext::atmospheres() {
+ STACK_CHECK;
+ cl = data.byte(kMapx);
+ ch = data.byte(kMapy);
+ bx = 5246;
+nextatmos:
+ al = cs.byte(bx);
+ _cmp(al, 255);
+ if (flags.z())
+ goto nomoreatmos;
+ _cmp(al, data.byte(kReallocation));
+ if (!flags.z())
+ goto wrongatmos;
+ ax = cs.word(bx+1);
+ _cmp(ax, cx);
+ if (!flags.z())
+ goto wrongatmos;
+ ax = cs.word(bx+3);
+ _cmp(al, data.byte(kCh0playing));
+ if (flags.z())
+ goto playingalready;
+ _cmp(data.byte(kLocation), 45);
+ if (!flags.z())
+ goto notweb;
+ _cmp(data.word(kReeltowatch), 45);
+ if (flags.z())
+ goto wrongatmos;
+notweb:
+ playchannel0();
+ _cmp(data.byte(kReallocation), 2);
+ _cmp(data.byte(kMapy), 0);
+ if (flags.z())
+ goto fullvol;
+ if (!flags.z())
+ goto notlouisvol;
+ _cmp(data.byte(kMapy), 10);
+ if (!flags.z())
+ goto notlouisvol;
+ _cmp(data.byte(kMapx), 22);
+ if (!flags.z())
+ goto notlouisvol;
+ data.byte(kVolume) = 5;
+notlouisvol:
+ _cmp(data.byte(kReallocation), 14);
+ if (!flags.z())
+ goto notmad1;
+ _cmp(data.byte(kMapx), 33);
+ if (flags.z())
+ goto ismad2;
+ _cmp(data.byte(kMapx), 22);
+ if (!flags.z())
+ goto notmad1;
+ data.byte(kVolume) = 5;
+ return;
+ismad2:
+ data.byte(kVolume) = 0;
+ return;
+notmad1:
+playingalready:
+ _cmp(data.byte(kReallocation), 2);
+ if (!flags.z())
+ return /* (notlouisvol2) */;
+ _cmp(data.byte(kMapx), 22);
+ if (flags.z())
+ goto louisvol;
+ _cmp(data.byte(kMapx), 11);
+ if (!flags.z())
+ return /* (notlouisvol2) */;
+fullvol:
+ data.byte(kVolume) = 0;
+ return;
+louisvol:
+ data.byte(kVolume) = 5;
+ return;
+wrongatmos:
+ _add(bx, 5);
+ goto nextatmos;
+nomoreatmos:
+ cancelch0();
+}
+
+void DreamGenContext::walkintoroom() {
+ STACK_CHECK;
+ _cmp(data.byte(kLocation), 14);
+ if (!flags.z())
+ return /* (notlair) */;
+ _cmp(data.byte(kMapx), 22);
+ if (!flags.z())
+ return /* (notlair) */;
+ data.byte(kDestination) = 1;
+ data.byte(kFinaldest) = 1;
+ autosetwalk();
+}
+
+void DreamGenContext::afterintroroom() {
+ STACK_CHECK;
+ _cmp(data.byte(kNowinnewroom), 0);
+ if (flags.z())
+ return /* (notnewintro) */;
+ clearwork();
+ findroominloc();
+ data.byte(kNewobs) = 1;
+ drawfloor();
+ reelsonscreen();
+ spriteupdate();
+ printsprites();
+ worktoscreen();
+ data.byte(kNowinnewroom) = 0;
+}
+
+void DreamGenContext::obname() {
+ STACK_CHECK;
+ _cmp(data.byte(kReasseschanges), 0);
+ if (flags.z())
+ goto notnewpath;
+ data.byte(kReasseschanges) = 0;
+ goto diff;
+notnewpath:
+ _cmp(ah, data.byte(kCommandtype));
+ if (flags.z())
+ goto notdiffob;
+ goto diff;
+notdiffob:
+ _cmp(al, data.byte(kCommand));
+ if (!flags.z())
+ goto diff;
+ _cmp(data.byte(kWalkandexam), 1);
+ if (flags.z())
+ goto walkandexamine;
+ _cmp(data.word(kMousebutton), 0);
+ if (flags.z())
+ return /* (noobselect) */;
+ _cmp(data.byte(kCommandtype), 3);
+ if (!flags.z())
+ goto isntblock;
+ _cmp(data.byte(kLastflag), 2);
+ if (flags.c())
+ return /* (noobselect) */;
+isntblock:
+ bl = data.byte(kManspath);
+ _cmp(bl, data.byte(kPointerspath));
+ if (!flags.z())
+ goto wantstowalk;
+ _cmp(data.byte(kCommandtype), 3);
+ if (flags.z())
+ goto wantstowalk;
+ finishedwalking();
+ if (!flags.z())
+ return /* (noobselect) */;
+ _cmp(data.byte(kCommandtype), 5);
+ if (flags.z())
+ goto wantstotalk;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ return /* (noobselect) */;
+ examineob();
+ return;
+wantstotalk:
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ return /* (noobselect) */;
+ talk();
+ return;
+walkandexamine:
+ finishedwalking();
+ if (!flags.z())
+ return /* (noobselect) */;
+ al = data.byte(kWalkexamtype);
+ data.byte(kCommandtype) = al;
+ al = data.byte(kWalkexamnum);
+ data.byte(kCommand) = al;
+ data.byte(kWalkandexam) = 0;
+ _cmp(data.byte(kCommandtype), 5);
+ if (flags.z())
+ return /* (noobselect) */;
+ examineob();
+ return;
+wantstowalk:
+ setwalk();
+ data.byte(kReasseschanges) = 1;
+ return;
+diff:
+ data.byte(kCommand) = al;
+ data.byte(kCommandtype) = ah;
+ _cmp(data.byte(kLinepointer), 254);
+ if (!flags.z())
+ goto middleofwalk;
+ _cmp(data.word(kWatchingtime), 0);
+ if (!flags.z())
+ goto middleofwalk;
+ al = data.byte(kFacing);
+ _cmp(al, data.byte(kTurntoface));
+ if (!flags.z())
+ goto middleofwalk;
+ _cmp(data.byte(kCommandtype), 3);
+ if (!flags.z())
+ goto notblock;
+ bl = data.byte(kManspath);
+ _cmp(bl, data.byte(kPointerspath));
+ if (!flags.z())
+ goto dontcheck;
+ cl = data.byte(kRyanx);
+ _add(cl, 12);
+ ch = data.byte(kRyany);
+ _add(ch, 12);
+ checkone();
+ _cmp(cl, 2);
+ if (flags.c())
+ goto isblock;
+dontcheck:
+ getflagunderp();
+ _cmp(data.byte(kLastflag), 2);
+ if (flags.c())
+ goto isblock;
+ _cmp(data.byte(kLastflag), 128);
+ if (!flags.c())
+ goto isblock;
+ goto toofaraway;
+notblock:
+ bl = data.byte(kManspath);
+ _cmp(bl, data.byte(kPointerspath));
+ if (!flags.z())
+ goto toofaraway;
+ _cmp(data.byte(kCommandtype), 3);
+ if (flags.z())
+ goto isblock;
+ _cmp(data.byte(kCommandtype), 5);
+ if (flags.z())
+ goto isaperson;
+ examineobtext();
+ return;
+middleofwalk:
+ blocknametext();
+ return;
+isblock:
+ blocknametext();
+ return;
+isaperson:
+ personnametext();
+ return;
+toofaraway:
+ walktotext();
+}
+
+void DreamGenContext::finishedwalking() {
+ STACK_CHECK;
+ _cmp(data.byte(kLinepointer), 254);
+ if (!flags.z())
+ return /* (iswalking) */;
+ al = data.byte(kFacing);
+ _cmp(al, data.byte(kTurntoface));
+}
+
+void DreamGenContext::examineobtext() {
+ STACK_CHECK;
+ bl = data.byte(kCommand);
+ bh = data.byte(kCommandtype);
+ al = 1;
+ commandwithob();
+}
+
+void DreamGenContext::commandwithob() {
+ STACK_CHECK;
+ push(ax);
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ push(es);
+ push(ds);
+ push(si);
+ push(di);
+ deltextline();
+ di = pop();
+ si = pop();
+ ds = pop();
+ es = pop();
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+ push(bx);
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ es = data.word(kCommandtext);
+ ax = es.word(bx);
+ _add(ax, (66*2));
+ si = ax;
+ di = data.word(kTextaddressx);
+ bx = data.word(kTextaddressy);
+ dl = data.byte(kTextlen);
+ al = 0;
+ ah = 0;
+ printdirect();
+ ax = pop();
+ di = 5847;
+ copyname();
+ ax = pop();
+ di = data.word(kLastxpos);
+ _cmp(al, 0);
+ if (flags.z())
+ goto noadd;
+ _add(di, 5);
+noadd:
+ bx = data.word(kTextaddressy);
+ es = cs;
+ si = 5847;
+ dl = data.byte(kTextlen);
+ al = 0;
+ ah = 0;
+ printdirect();
+ data.byte(kNewtextline) = 1;
+}
+
+void DreamGenContext::commandonly() {
+ STACK_CHECK;
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ push(es);
+ push(ds);
+ push(si);
+ push(di);
+ deltextline();
+ di = pop();
+ si = pop();
+ ds = pop();
+ es = pop();
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ es = data.word(kCommandtext);
+ ax = es.word(bx);
+ _add(ax, (66*2));
+ si = ax;
+ di = data.word(kTextaddressx);
+ bx = data.word(kTextaddressy);
+ dl = data.byte(kTextlen);
+ al = 0;
+ ah = 0;
+ printdirect();
+ data.byte(kNewtextline) = 1;
+}
+
+void DreamGenContext::printmessage() {
+ STACK_CHECK;
+ push(dx);
+ push(bx);
+ push(di);
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ es = data.word(kCommandtext);
+ ax = es.word(bx);
+ _add(ax, (66*2));
+ si = ax;
+ di = pop();
+ bx = pop();
+ dx = pop();
+ al = 0;
+ ah = 0;
+ printdirect();
+}
+
+void DreamGenContext::printmessage2() {
+ STACK_CHECK;
+ push(dx);
+ push(bx);
+ push(di);
+ push(ax);
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ es = data.word(kCommandtext);
+ ax = es.word(bx);
+ _add(ax, (66*2));
+ si = ax;
+ ax = pop();
+searchmess:
+ push(ax);
+ findnextcolon();
+ ax = pop();
+ _dec(ah);
+ if (!flags.z())
+ goto searchmess;
+ di = pop();
+ bx = pop();
+ dx = pop();
+ al = 0;
+ ah = 0;
+ printdirect();
+}
+
+void DreamGenContext::blocknametext() {
+ STACK_CHECK;
+ bl = data.byte(kCommand);
+ bh = data.byte(kCommandtype);
+ al = 0;
+ commandwithob();
+}
+
+void DreamGenContext::personnametext() {
+ STACK_CHECK;
+ bl = data.byte(kCommand);
+ _and(bl, 127);
+ bh = data.byte(kCommandtype);
+ al = 2;
+ commandwithob();
+}
+
+void DreamGenContext::walktotext() {
+ STACK_CHECK;
+ bl = data.byte(kCommand);
+ bh = data.byte(kCommandtype);
+ al = 3;
+ commandwithob();
+}
+
+void DreamGenContext::getflagunderp() {
+ STACK_CHECK;
+ cx = data.word(kMousex);
+ _sub(cx, data.word(kMapadx));
+ ax = data.word(kMousey);
+ _sub(ax, data.word(kMapady));
+ ch = al;
+ checkone();
+ data.byte(kLastflag) = cl;
+ data.byte(kLastflagex) = ch;
+}
+
+void DreamGenContext::setwalk() {
+ STACK_CHECK;
+ _cmp(data.byte(kLinepointer), 254);
+ if (!flags.z())
+ goto alreadywalking;
+ al = data.byte(kPointerspath);
+ _cmp(al, data.byte(kManspath));
+ if (flags.z())
+ goto cantwalk2;
+ _cmp(data.byte(kWatchmode), 1);
+ if (flags.z())
+ goto holdingreel;
+ _cmp(data.byte(kWatchmode), 2);
+ if (flags.z())
+ return /* (cantwalk) */;
+ data.byte(kDestination) = al;
+ data.byte(kFinaldest) = al;
+ _cmp(data.word(kMousebutton), 2);
+ if (!flags.z())
+ goto notwalkandexam;
+ _cmp(data.byte(kCommandtype), 3);
+ if (flags.z())
+ goto notwalkandexam;
+ data.byte(kWalkandexam) = 1;
+ al = data.byte(kCommandtype);
+ data.byte(kWalkexamtype) = al;
+ al = data.byte(kCommand);
+ data.byte(kWalkexamnum) = al;
+notwalkandexam:
+ autosetwalk();
+ return;
+cantwalk2:
+ facerightway();
+ return;
+alreadywalking:
+ al = data.byte(kPointerspath);
+ data.byte(kFinaldest) = al;
+ return;
+holdingreel:
+ data.byte(kDestafterhold) = al;
+ data.byte(kWatchmode) = 2;
+}
+
+void DreamGenContext::autosetwalk() {
+ STACK_CHECK;
+ al = data.byte(kManspath);
+ _cmp(data.byte(kFinaldest), al);
+ if (!flags.z())
+ goto notsamealready;
+ return;
+notsamealready:
+ getroomspaths();
+ checkdest();
+ push(bx);
+ al = data.byte(kManspath);
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = es.byte(bx);
+ ah = 0;
+ _sub(ax, 12);
+ data.word(kLinestartx) = ax;
+ al = es.byte(bx+1);
+ ah = 0;
+ _sub(ax, 12);
+ data.word(kLinestarty) = ax;
+ bx = pop();
+ al = data.byte(kDestination);
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = es.byte(bx);
+ ah = 0;
+ _sub(ax, 12);
+ data.word(kLineendx) = ax;
+ al = es.byte(bx+1);
+ ah = 0;
+ _sub(ax, 12);
+ data.word(kLineendy) = ax;
+ bresenhams();
+ _cmp(data.byte(kLinedirection), 0);
+ if (flags.z())
+ goto normalline;
+ al = data.byte(kLinelength);
+ _dec(al);
+ data.byte(kLinepointer) = al;
+ data.byte(kLinedirection) = 1;
+ return;
+normalline:
+ data.byte(kLinepointer) = 0;
+}
+
+void DreamGenContext::checkdest() {
+ STACK_CHECK;
+ push(bx);
+ _add(bx, 12*8);
+ ah = data.byte(kManspath);
+ cl = 4;
+ _shl(ah, cl);
+ al = data.byte(kDestination);
+ cl = 24;
+ ch = data.byte(kDestination);
+checkdestloop:
+ dh = es.byte(bx);
+ _and(dh, 0xf0);
+ dl = es.byte(bx);
+ _and(dl, 0xf);
+ _cmp(ax, dx);
+ if (!flags.z())
+ goto nextcheck;
+ al = es.byte(bx+1);
+ _and(al, 15);
+ data.byte(kDestination) = al;
+ bx = pop();
+ return;
+nextcheck:
+ dl = es.byte(bx);
+ _and(dl, 0xf0);
+ _shr(dl, 1);
+ _shr(dl, 1);
+ _shr(dl, 1);
+ _shr(dl, 1);
+ dh = es.byte(bx);
+ _and(dh, 0xf);
+ _shl(dh, 1);
+ _shl(dh, 1);
+ _shl(dh, 1);
+ _shl(dh, 1);
+ _cmp(ax, dx);
+ if (!flags.z())
+ goto nextcheck2;
+ ch = es.byte(bx+1);
+ _and(ch, 15);
+nextcheck2:
+ _add(bx, 2);
+ _dec(cl);
+ if (!flags.z())
+ goto checkdestloop;
+ data.byte(kDestination) = ch;
+ bx = pop();
+}
+
+void DreamGenContext::bresenhams() {
+ STACK_CHECK;
+ workoutframes();
+ dx = data;
+ es = dx;
+ di = 8173;
+ si = 1;
+ data.byte(kLinedirection) = 0;
+ cx = data.word(kLineendx);
+ _sub(cx, data.word(kLinestartx));
+ if (flags.z())
+ goto vertline;
+ if (!flags.s())
+ goto line1;
+ _neg(cx);
+ bx = data.word(kLineendx);
+ _xchg(bx, data.word(kLinestartx));
+ data.word(kLineendx) = bx;
+ bx = data.word(kLineendy);
+ _xchg(bx, data.word(kLinestarty));
+ data.word(kLineendy) = bx;
+ data.byte(kLinedirection) = 1;
+line1:
+ bx = data.word(kLineendy);
+ _sub(bx, data.word(kLinestarty));
+ if (flags.z())
+ goto horizline;
+ if (!flags.s())
+ goto line3;
+ _neg(bx);
+ _neg(si);
+line3:
+ push(si);
+ data.byte(kLineroutine) = 0;
+ _cmp(bx, cx);
+ if (flags.le())
+ goto line4;
+ data.byte(kLineroutine) = 1;
+ _xchg(bx, cx);
+line4:
+ _shl(bx, 1);
+ data.word(kIncrement1) = bx;
+ _sub(bx, cx);
+ si = bx;
+ _sub(bx, cx);
+ data.word(kIncrement2) = bx;
+ ax = data.word(kLinestartx);
+ bx = data.word(kLinestarty);
+ ah = bl;
+ _inc(cx);
+ bx = pop();
+ _cmp(data.byte(kLineroutine), 1);
+ if (flags.z())
+ goto hislope;
+ goto loslope;
+vertline:
+ ax = data.word(kLinestarty);
+ bx = data.word(kLineendy);
+ cx = bx;
+ _sub(cx, ax);
+ if (!flags.l())
+ goto line31;
+ _neg(cx);
+ ax = bx;
+ data.byte(kLinedirection) = 1;
+line31:
+ _inc(cx);
+ bx = data.word(kLinestartx);
+ _xchg(ax, bx);
+ ah = bl;
+ bx = si;
+line32:
+ _stosw();
+ _add(ah, bl);
+ if (--cx)
+ goto line32;
+ goto lineexit;
+horizline:
+ ax = data.word(kLinestartx);
+ bx = data.word(kLinestarty);
+ ah = bl;
+ _inc(cx);
+horizloop:
+ _stosw();
+ _inc(al);
+ if (--cx)
+ goto horizloop;
+ goto lineexit;
+loslope:
+loloop:
+ _stosw();
+ _inc(al);
+ _or(si, si);
+ if (!flags.s())
+ goto line12;
+ _add(si, data.word(kIncrement1));
+ if (--cx)
+ goto loloop;
+ goto lineexit;
+line12:
+ _add(si, data.word(kIncrement2));
+ _add(ah, bl);
+ if (--cx)
+ goto loloop;
+ goto lineexit;
+hislope:
+hiloop:
+ _stosw();
+ _add(ah, bl);
+ _or(si, si);
+ if (!flags.s())
+ goto line23;
+ _add(si, data.word(kIncrement1));
+ if (--cx)
+ goto hiloop;
+ goto lineexit;
+line23:
+ _add(si, data.word(kIncrement2));
+ _inc(al);
+ if (--cx)
+ goto hiloop;
+lineexit:
+ _sub(di, 8173);
+ ax = di;
+ _shr(ax, 1);
+ data.byte(kLinelength) = al;
+}
+
+void DreamGenContext::workoutframes() {
+ STACK_CHECK;
+ bx = data.word(kLinestartx);
+ _add(bx, 32);
+ ax = data.word(kLineendx);
+ _add(ax, 32);
+ _sub(bx, ax);
+ if (!flags.c())
+ goto notneg1;
+ _neg(bx);
+notneg1:
+ cx = data.word(kLinestarty);
+ _add(cx, 32);
+ ax = data.word(kLineendy);
+ _add(ax, 32);
+ _sub(cx, ax);
+ if (!flags.c())
+ goto notneg2;
+ _neg(cx);
+notneg2:
+ _cmp(bx, cx);
+ if (!flags.c())
+ goto tendstohoriz;
+ dl = 2;
+ ax = cx;
+ _shr(ax, 1);
+ _cmp(bx, ax);
+ if (flags.c())
+ goto gotquad;
+ dl = 1;
+ goto gotquad;
+tendstohoriz:
+ dl = 0;
+ ax = bx;
+ _shr(ax, 1);
+ _cmp(cx, ax);
+ if (flags.c())
+ goto gotquad;
+ dl = 1;
+ goto gotquad;
+gotquad:
+ bx = data.word(kLinestartx);
+ _add(bx, 32);
+ ax = data.word(kLineendx);
+ _add(ax, 32);
+ _sub(bx, ax);
+ if (flags.c())
+ goto isinright;
+ cx = data.word(kLinestarty);
+ _add(cx, 32);
+ ax = data.word(kLineendy);
+ _add(ax, 32);
+ _sub(cx, ax);
+ if (!flags.c())
+ goto topleft;
+ _cmp(dl, 1);
+ if (flags.z())
+ goto noswap1;
+ _xor(dl, 2);
+noswap1:
+ _add(dl, 4);
+ goto success;
+topleft:
+ _add(dl, 6);
+ goto success;
+isinright:
+ cx = data.word(kLinestarty);
+ _add(cx, 32);
+ ax = data.word(kLineendy);
+ _add(ax, 32);
+ _sub(cx, ax);
+ if (!flags.c())
+ goto botright;
+ _add(dl, 2);
+ goto success;
+botright:
+ _cmp(dl, 1);
+ if (flags.z())
+ goto noswap2;
+ _xor(dl, 2);
+noswap2:
+success:
+ _and(dl, 7);
+ data.byte(kTurntoface) = dl;
+ data.byte(kTurndirection) = 0;
+}
+
+void DreamGenContext::getroomspaths() {
+ STACK_CHECK;
+ al = data.byte(kRoomnum);
+ ah = 0;
+ cx = 144;
+ _mul(cx);
+ es = data.word(kReels);
+ bx = (0);
+ _add(bx, ax);
+}
+
+void DreamGenContext::copyname() {
+ STACK_CHECK;
+ push(di);
+ findobname();
+ di = pop();
+ es = cs;
+ cx = 28;
+make:
+ _lodsb();
+ _cmp(al, ':');
+ if (flags.z())
+ goto finishmakename;
+ _cmp(al, 0);
+ if (flags.z())
+ goto finishmakename;
+ _stosb();
+ if (--cx)
+ goto make;
+finishmakename:
+ _inc(cx);
+ al = 0;
+ _stosb();
+ return;
+ al = 255;
+ _stosb(cx, true);
+}
+
+void DreamGenContext::findobname() {
+ STACK_CHECK;
+ push(ax);
+ ah = 0;
+ _add(ax, ax);
+ bx = ax;
+ ax = pop();
+ _cmp(ah, 5);
+ if (!flags.z())
+ goto notpersonname;
+ push(ax);
+ _and(al, 127);
+ ah = 0;
+ bx = 64*2;
+ _mul(bx);
+ si = ax;
+ ds = data.word(kPeople);
+ _add(si, (0+24));
+ cx = (0+24+(1026*2));
+ ax = ds.word(si);
+ _add(ax, cx);
+ si = ax;
+ ax = pop();
+ return;
+notpersonname:
+ _cmp(ah, 4);
+ if (!flags.z())
+ goto notextraname;
+ ds = data.word(kExtras);
+ _add(bx, (0+2080+30000+(16*114)));
+ ax = ds.word(bx);
+ _add(ax, (0+2080+30000+(16*114)+((114+2)*2)));
+ si = ax;
+ return;
+notextraname:
+ _cmp(ah, 2);
+ if (!flags.z())
+ goto notfreename;
+ ds = data.word(kFreedesc);
+ _add(bx, (0));
+ ax = ds.word(bx);
+ _add(ax, (0+(82*2)));
+ si = ax;
+ return;
+notfreename:
+ _cmp(ah, 1);
+ if (!flags.z())
+ goto notsetname;
+ ds = data.word(kSetdesc);
+ _add(bx, (0));
+ ax = ds.word(bx);
+ _add(ax, (0+(130*2)));
+ si = ax;
+ return;
+notsetname:
+ ds = data.word(kBlockdesc);
+ _add(bx, (0));
+ ax = ds.word(bx);
+ _add(ax, (0+(98*2)));
+ si = ax;
+}
+
+void DreamGenContext::showicon() {
+ STACK_CHECK;
+ _cmp(data.byte(kReallocation), 50);
+ if (!flags.c())
+ goto isdream1;
+ showpanel();
+ showman();
+ roomname();
+ panelicons1();
+ zoomicon();
+ return;
+isdream1:
+ ds = data.word(kTempsprites);
+ di = 72;
+ bx = 2;
+ al = 45;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 72+47;
+ bx = 2;
+ al = 46;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 69-10;
+ bx = 21;
+ al = 49;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 160+88;
+ bx = 2;
+ al = 45;
+ ah = 4;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 160+43;
+ bx = 2;
+ al = 46;
+ ah = 4;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 160+101;
+ bx = 21;
+ al = 49;
+ ah = 4;
+ showframe();
+ middlepanel();
+}
+
+void DreamGenContext::middlepanel() {
+ STACK_CHECK;
+ ds = data.word(kTempsprites);
+ di = 72+47+20;
+ bx = 0;
+ al = 48;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 72+19;
+ bx = 21;
+ al = 47;
+ ah = 0;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 160+23;
+ bx = 0;
+ al = 48;
+ ah = 4;
+ showframe();
+ ds = data.word(kTempsprites);
+ di = 160+71;
+ bx = 21;
+ al = 47;
+ ah = 4;
+ showframe();
+}
+
+void DreamGenContext::showman() {
+ STACK_CHECK;
+ ds = data.word(kIcons1);
+ di = 0;
+ bx = 0;
+ al = 0;
+ ah = 0;
+ showframe();
+ ds = data.word(kIcons1);
+ di = 0;
+ bx = 114;
+ al = 1;
+ ah = 0;
+ showframe();
+ _cmp(data.byte(kShadeson), 0);
+ if (flags.z())
+ return /* (notverycool) */;
+ ds = data.word(kIcons1);
+ di = 28;
+ bx = 25;
+ al = 2;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::showpanel() {
+ STACK_CHECK;
+ ds = data.word(kIcons1);
+ di = 72;
+ bx = 0;
+ al = 19;
+ ah = 0;
+ showframe();
+ ds = data.word(kIcons1);
+ di = 192;
+ bx = 0;
+ al = 19;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::roomname() {
+ STACK_CHECK;
+ di = 88;
+ bx = 18;
+ al = 53;
+ dl = 240;
+ printmessage();
+ bl = data.byte(kRoomnum);
+ _cmp(bl, 32);
+ if (flags.c())
+ goto notover32;
+ _sub(bl, 32);
+notover32:
+ bh = 0;
+ _add(bx, bx);
+ es = data.word(kRoomdesc);
+ _add(bx, (0));
+ ax = es.word(bx);
+ _add(ax, (0+(38*2)));
+ si = ax;
+ data.word(kLinespacing) = 7;
+ di = 88;
+ bx = 25;
+ dl = 120;
+ _cmp(data.byte(kWatchon), 1);
+ if (flags.z())
+ goto gotpl;
+ dl = 160;
+gotpl:
+ al = 0;
+ ah = 0;
+ printdirect();
+ data.word(kLinespacing) = 10;
+ usecharset1();
+}
+
+void DreamGenContext::usecharset1() {
+ STACK_CHECK;
+ ax = data.word(kCharset1);
+ data.word(kCurrentset) = ax;
+}
+
+void DreamGenContext::usetempcharset() {
+ STACK_CHECK;
+ ax = data.word(kTempcharset);
+ data.word(kCurrentset) = ax;
+}
+
+void DreamGenContext::showexit() {
+ STACK_CHECK;
+ ds = data.word(kIcons1);
+ di = 274;
+ bx = 154;
+ al = 11;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::panelicons1() {
+ STACK_CHECK;
+ di = 0;
+ _cmp(data.byte(kWatchon), 1);
+ if (flags.z())
+ goto watchison;
+ di = 48;
+watchison:
+ push(di);
+ ds = data.word(kIcons2);
+ _add(di, 204);
+ bx = 4;
+ al = 2;
+ ah = 0;
+ showframe();
+ di = pop();
+ push(di);
+ _cmp(data.byte(kZoomon), 1);
+ if (flags.z())
+ goto zoomisoff;
+ ds = data.word(kIcons1);
+ _add(di, 228);
+ bx = 8;
+ al = 5;
+ ah = 0;
+ showframe();
+zoomisoff:
+ di = pop();
+ showwatch();
+}
+
+void DreamGenContext::showwatch() {
+ STACK_CHECK;
+ _cmp(data.byte(kWatchon), 0);
+ if (flags.z())
+ return /* (nowristwatch) */;
+ ds = data.word(kIcons1);
+ di = 250;
+ bx = 1;
+ al = 6;
+ ah = 0;
+ showframe();
+ showtime();
+}
+
+void DreamGenContext::zoomicon() {
+ STACK_CHECK;
+ _cmp(data.byte(kZoomon), 0);
+ if (flags.z())
+ return /* (nozoom1) */;
+ ds = data.word(kIcons1);
+ di = (8);
+ bx = (132)-1;
+ al = 8;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::showblink() {
+ STACK_CHECK;
+ _cmp(data.byte(kManisoffscreen), 1);
+ if (flags.z())
+ return /* (finblink1) */;
+ _inc(data.byte(kBlinkcount));
+ _cmp(data.byte(kShadeson), 0);
+ if (!flags.z())
+ return /* (finblink1) */;
+ _cmp(data.byte(kReallocation), 50);
+ if (!flags.c())
+ return /* (eyesshut) */;
+ al = data.byte(kBlinkcount);
+ _cmp(al, 3);
+ if (!flags.z())
+ return /* (finblink1) */;
+ data.byte(kBlinkcount) = 0;
+ al = data.byte(kBlinkframe);
+ _inc(al);
+ data.byte(kBlinkframe) = al;
+ _cmp(al, 6);
+ if (flags.c())
+ goto nomorethan6;
+ al = 6;
+nomorethan6:
+ ah = 0;
+ bx = 5888;
+ _add(bx, ax);
+ al = cs.byte(bx);
+ ds = data.word(kIcons1);
+ di = 44;
+ bx = 32;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::dumpblink() {
+ STACK_CHECK;
+ _cmp(data.byte(kShadeson), 0);
+ if (!flags.z())
+ return /* (nodumpeye) */;
+ _cmp(data.byte(kBlinkcount), 0);
+ if (!flags.z())
+ return /* (nodumpeye) */;
+ al = data.byte(kBlinkframe);
+ _cmp(al, 6);
+ if (!flags.c())
+ return /* (nodumpeye) */;
+ push(ds);
+ di = 44;
+ bx = 32;
+ cl = 16;
+ ch = 12;
+ multidump();
+ ds = pop();
+}
+
+void DreamGenContext::worktoscreenm() {
+ STACK_CHECK;
+ animpointer();
+ readmouse();
+ showpointer();
+ vsync();
+ worktoscreen();
+ delpointer();
+}
+
+void DreamGenContext::blank() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 199);
+ if (flags.z())
+ return /* (alreadyblnk) */;
+ data.byte(kCommandtype) = 199;
+ al = 0;
+ commandonly();
+}
+
+void DreamGenContext::allpointer() {
+ STACK_CHECK;
+ readmouse();
+ showpointer();
+ dumppointer();
+}
+
+void DreamGenContext::hangonp() {
+ STACK_CHECK;
+ push(cx);
+ _add(cx, cx);
+ ax = pop();
+ _add(cx, ax);
+ data.word(kMaintimer) = 0;
+ al = data.byte(kPointerframe);
+ ah = data.byte(kPickup);
+ push(ax);
+ data.byte(kPointermode) = 3;
+ data.byte(kPickup) = 0;
+ push(cx);
+ data.byte(kCommandtype) = 255;
+ readmouse();
+ animpointer();
+ showpointer();
+ vsync();
+ dumppointer();
+ cx = pop();
+hangloop:
+ push(cx);
+ delpointer();
+ readmouse();
+ animpointer();
+ showpointer();
+ vsync();
+ dumppointer();
+ cx = pop();
+ ax = data.word(kMousebutton);
+ _cmp(ax, 0);
+ if (flags.z())
+ goto notpressed;
+ _cmp(ax, data.word(kOldbutton));
+ if (!flags.z())
+ goto getoutofit;
+notpressed:
+ if (--cx)
+ goto hangloop;
+getoutofit:
+ delpointer();
+ ax = pop();
+ data.byte(kPointerframe) = al;
+ data.byte(kPickup) = ah;
+ data.byte(kPointermode) = 0;
+}
+
+void DreamGenContext::hangonw() {
+ STACK_CHECK;
+hangloopw:
+ push(cx);
+ delpointer();
+ readmouse();
+ animpointer();
+ showpointer();
+ vsync();
+ dumppointer();
+ cx = pop();
+ if (--cx)
+ goto hangloopw;
+}
+
+void DreamGenContext::hangoncurs() {
+ STACK_CHECK;
+monloop1:
+ push(cx);
+ printcurs();
+ vsync();
+ delcurs();
+ cx = pop();
+ if (--cx)
+ goto monloop1;
+}
+
+void DreamGenContext::getunderzoom() {
+ STACK_CHECK;
+ di = (8)+5;
+ bx = (132)+4;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5));
+ cl = 46;
+ ch = 40;
+ multiget();
+}
+
+void DreamGenContext::dumpzoom() {
+ STACK_CHECK;
+ _cmp(data.byte(kZoomon), 1);
+ if (!flags.z())
+ return /* (notzoomon) */;
+ di = (8)+5;
+ bx = (132)+4;
+ cl = 46;
+ ch = 40;
+ multidump();
+}
+
+void DreamGenContext::putunderzoom() {
+ STACK_CHECK;
+ di = (8)+5;
+ bx = (132)+4;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5));
+ cl = 46;
+ ch = 40;
+ multiput();
+}
+
+void DreamGenContext::crosshair() {
+ STACK_CHECK;
+ _cmp(data.byte(kCommandtype), 3);
+ if (flags.z())
+ goto nocross;
+ _cmp(data.byte(kCommandtype), 10);
+ if (!flags.c())
+ goto nocross;
+ es = data.word(kWorkspace);
+ ds = data.word(kIcons1);
+ di = (8)+24;
+ bx = (132)+19;
+ al = 9;
+ ah = 0;
+ showframe();
+ return;
+nocross:
+ es = data.word(kWorkspace);
+ ds = data.word(kIcons1);
+ di = (8)+24;
+ bx = (132)+19;
+ al = 29;
+ ah = 0;
+ showframe();
+}
+
+void DreamGenContext::showpointer() {
+ STACK_CHECK;
+ showblink();
+ di = data.word(kMousex);
+ data.word(kOldpointerx) = di;
+ bx = data.word(kMousey);
+ data.word(kOldpointery) = bx;
+ _cmp(data.byte(kPickup), 1);
+ if (flags.z())
+ goto itsanobject;
+ push(bx);
+ push(di);
+ ds = data.word(kIcons1);
+ al = data.byte(kPointerframe);
+ _add(al, 20);
+ ah = 0;
+ _add(ax, ax);
+ si = ax;
+ _add(ax, ax);
+ _add(si, ax);
+ cx = ds.word(si);
+ _cmp(cl, 12);
+ if (!flags.c())
+ goto notsmallx;
+ cl = 12;
+notsmallx:
+ _cmp(ch, 12);
+ if (!flags.c())
+ goto notsmally;
+ ch = 12;
+notsmally:
+ data.byte(kPointerxs) = cl;
+ data.byte(kPointerys) = ch;
+ push(ds);
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60);
+ multiget();
+ ds = pop();
+ di = pop();
+ bx = pop();
+ push(di);
+ push(bx);
+ al = data.byte(kPointerframe);
+ _add(al, 20);
+ ah = 0;
+ showframe();
+ bx = pop();
+ di = pop();
+ return;
+itsanobject:
+ al = data.byte(kItemframe);
+ ds = data.word(kExtras);
+ _cmp(data.byte(kObjecttype), 4);
+ if (flags.z())
+ goto itsfrominv;
+ ds = data.word(kFreeframes);
+itsfrominv:
+ cl = al;
+ _add(al, al);
+ _add(al, cl);
+ _inc(al);
+ ah = 0;
+ push(ax);
+ _add(ax, ax);
+ si = ax;
+ _add(ax, ax);
+ _add(si, ax);
+ ax = 2080;
+ cx = ds.word(si);
+ _cmp(cl, 12);
+ if (!flags.c())
+ goto notsmallx2;
+ cl = 12;
+notsmallx2:
+ _cmp(ch, 12);
+ if (!flags.c())
+ goto notsmally2;
+ ch = 12;
+notsmally2:
+ data.byte(kPointerxs) = cl;
+ data.byte(kPointerys) = ch;
+ ax = pop();
+ push(di);
+ push(bx);
+ push(ax);
+ push(bx);
+ push(di);
+ push(ds);
+ al = cl;
+ ah = 0;
+ _shr(ax, 1);
+ _sub(data.word(kOldpointerx), ax);
+ _sub(di, ax);
+ al = ch;
+ _shr(ax, 1);
+ _sub(data.word(kOldpointery), ax);
+ _sub(bx, ax);
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60);
+ multiget();
+ ds = pop();
+ di = pop();
+ bx = pop();
+ ax = pop();
+ ah = 128;
+ showframe();
+ bx = pop();
+ di = pop();
+ ds = data.word(kIcons1);
+ al = 3;
+ ah = 128;
+ showframe();
+}
+
+void DreamGenContext::delpointer() {
+ STACK_CHECK;
+ ax = data.word(kOldpointerx);
+ _cmp(ax, 0x0ffff);
+ if (flags.z())
+ return /* (nevershown) */;
+ data.word(kDelherex) = ax;
+ ax = data.word(kOldpointery);
+ data.word(kDelherey) = ax;
+ cl = data.byte(kPointerxs);
+ data.byte(kDelxs) = cl;
+ ch = data.byte(kPointerys);
+ data.byte(kDelys) = ch;
+ ds = data.word(kBuffers);
+ si = (0+(228*13)+32+60);
+ di = data.word(kDelherex);
+ bx = data.word(kDelherey);
+ multiput();
+}
+
+void DreamGenContext::dumppointer() {
+ STACK_CHECK;
+ dumpblink();
+ cl = data.byte(kDelxs);
+ ch = data.byte(kDelys);
+ di = data.word(kDelherex);
+ bx = data.word(kDelherey);
+ multidump();
+ bx = data.word(kOldpointery);
+ di = data.word(kOldpointerx);
+ _cmp(di, data.word(kDelherex));
+ if (!flags.z())
+ goto difffound;
+ _cmp(bx, data.word(kDelherey));
+ if (flags.z())
+ return /* (notboth) */;
+difffound:
+ cl = data.byte(kPointerxs);
+ ch = data.byte(kPointerys);
+ multidump();
+}
+
+void DreamGenContext::undertextline() {
+ STACK_CHECK;
+ di = data.word(kTextaddressx);
+ bx = data.word(kTextaddressy);
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(bx, 3);
+_tmp1:
+ ds = data.word(kBuffers);
+ si = (0);
+ cl = (228);
+ ch = (13);
+ multiget();
+}
+
+void DreamGenContext::deltextline() {
+ STACK_CHECK;
+ di = data.word(kTextaddressx);
+ bx = data.word(kTextaddressy);
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(bx, 3);
+_tmp1:
+ ds = data.word(kBuffers);
+ si = (0);
+ cl = (228);
+ ch = (13);
+ multiput();
+}
+
+void DreamGenContext::dumptextline() {
+ STACK_CHECK;
+ _cmp(data.byte(kNewtextline), 1);
+ if (!flags.z())
+ return /* (nodumptextline) */;
+ data.byte(kNewtextline) = 0;
+ di = data.word(kTextaddressx);
+ bx = data.word(kTextaddressy);
+ _cmp(data.byte(kForeignrelease), 0);
+ if (flags.z())
+ goto _tmp1;
+ _sub(bx, 3);
+_tmp1:
+ cl = (228);
+ ch = (13);
+ multidump();
+}
+
+void DreamGenContext::animpointer() {
+ STACK_CHECK;
+ _cmp(data.byte(kPointermode), 2);
+ if (flags.z())
+ goto combathand;
+ _cmp(data.byte(kPointermode), 3);
+ if (flags.z())
+ goto mousehand;
+ _cmp(data.word(kWatchingtime), 0);
+ if (flags.z())
+ goto notwatchpoint;
+ data.byte(kPointerframe) = 11;
+ return;
+notwatchpoint:
+ data.byte(kPointerframe) = 0;
+ _cmp(data.byte(kInmaparea), 0);
+ if (flags.z())
+ return /* (gothand) */;
+ _cmp(data.byte(kPointerfirstpath), 0);
+ if (flags.z())
+ return /* (gothand) */;
+ getflagunderp();
+ _cmp(cl, 2);
+ if (flags.c())
+ return /* (gothand) */;
+ _cmp(cl, 128);
+ if (!flags.c())
+ return /* (gothand) */;
+ data.byte(kPointerframe) = 3;
+ _test(cl, 4);
+ if (!flags.z())
+ return /* (gothand) */;
+ data.byte(kPointerframe) = 4;
+ _test(cl, 16);
+ if (!flags.z())
+ return /* (gothand) */;
+ data.byte(kPointerframe) = 5;
+ _test(cl, 2);
+ if (!flags.z())
+ return /* (gothand) */;
+ data.byte(kPointerframe) = 6;
+ _test(cl, 8);
+ if (!flags.z())
+ return /* (gothand) */;
+ data.byte(kPointerframe) = 8;
+ return;
+mousehand:
+ _cmp(data.byte(kPointerspeed), 0);
+ if (flags.z())
+ goto rightspeed3;
+ _dec(data.byte(kPointerspeed));
+ goto finflashmouse;
+rightspeed3:
+ data.byte(kPointerspeed) = 5;
+ _inc(data.byte(kPointercount));
+ _cmp(data.byte(kPointercount), 16);
+ if (!flags.z())
+ goto finflashmouse;
+ data.byte(kPointercount) = 0;
+finflashmouse:
+ al = data.byte(kPointercount);
+ ah = 0;
+ bx = 5895;
+ _add(bx, ax);
+ al = cs.byte(bx);
+ data.byte(kPointerframe) = al;
+ return;
+combathand:
+ data.byte(kPointerframe) = 0;
+ _cmp(data.byte(kReallocation), 14);
+ if (!flags.z())
+ return /* (notarrow) */;
+ _cmp(data.byte(kCommandtype), 211);
+ if (!flags.z())
+ return /* (notarrow) */;
+ data.byte(kPointerframe) = 5;
+}
+
+void DreamGenContext::readmouse() {
+ STACK_CHECK;
+ ax = data.word(kMousebutton);
+ data.word(kOldbutton) = ax;
+ ax = data.word(kMousex);
+ data.word(kOldx) = ax;
+ ax = data.word(kMousey);
+ data.word(kOldy) = ax;
+ mousecall();
+ data.word(kMousex) = cx;
+ data.word(kMousey) = dx;
+ data.word(kMousebutton) = bx;
+}
+
+void DreamGenContext::readmouse1() {
+ STACK_CHECK;
+ ax = data.word(kMousex);
+ data.word(kOldx) = ax;
+ ax = data.word(kMousey);
+ data.word(kOldy) = ax;
+ mousecall();
+ data.word(kMousex) = cx;
+ data.word(kMousey) = dx;
+ data.word(kMousebutton1) = bx;
+}
+
+void DreamGenContext::readmouse2() {
+ STACK_CHECK;
+ ax = data.word(kMousex);
+ data.word(kOldx) = ax;
+ ax = data.word(kMousey);
+ data.word(kOldy) = ax;
+ mousecall();
+ data.word(kMousex) = cx;
+ data.word(kMousey) = dx;
+ data.word(kMousebutton2) = bx;
+}
+
+void DreamGenContext::readmouse3() {
+ STACK_CHECK;
+ ax = data.word(kMousex);
+ data.word(kOldx) = ax;
+ ax = data.word(kMousey);
+ data.word(kOldy) = ax;
+ mousecall();
+ data.word(kMousex) = cx;
+ data.word(kMousey) = dx;
+ data.word(kMousebutton3) = bx;
+}
+
+void DreamGenContext::readmouse4() {
+ STACK_CHECK;
+ ax = data.word(kMousebutton);
+ data.word(kOldbutton) = ax;
+ ax = data.word(kMousex);
+ data.word(kOldx) = ax;
+ ax = data.word(kMousey);
+ data.word(kOldy) = ax;
+ mousecall();
+ data.word(kMousex) = cx;
+ data.word(kMousey) = dx;
+ ax = data.word(kMousebutton1);
+ _or(ax, data.word(kMousebutton2));
+ _or(ax, data.word(kMousebutton3));
+ _or(bx, ax);
+ data.word(kMousebutton) = bx;
+}
+
+void DreamGenContext::readkey() {
+ STACK_CHECK;
+ bx = data.word(kBufferout);
+ _cmp(bx, data.word(kBufferin));
+ if (flags.z())
+ goto nokey;
+ _inc(bx);
+ _and(bx, 15);
+ data.word(kBufferout) = bx;
+ di = 5912;
+ _add(di, bx);
+ al = cs.byte(di);
+ data.byte(kCurrentkey) = al;
+ return;
+nokey:
+ data.byte(kCurrentkey) = 0;
+}
+
+void DreamGenContext::randomnum1() {
+ STACK_CHECK;
+ push(ds);
+ push(es);
+ push(di);
+ push(bx);
+ push(cx);
+ randomnumber();
+ cx = pop();
+ bx = pop();
+ di = pop();
+ es = pop();
+ ds = pop();
+}
+
+void DreamGenContext::randomnum2() {
+ STACK_CHECK;
+ push(ds);
+ push(es);
+ push(di);
+ push(bx);
+ push(ax);
+ randomnumber();
+ cl = al;
+ ax = pop();
+ bx = pop();
+ di = pop();
+ es = pop();
+ ds = pop();
+}
+
+void DreamGenContext::hangon() {
+ STACK_CHECK;
+hangonloop:
+ push(cx);
+ vsync();
+ cx = pop();
+ if (--cx)
+ goto hangonloop;
+}
+
+void DreamGenContext::loadtraveltext() {
+ STACK_CHECK;
+ dx = 2234;
+ standardload();
+ data.word(kTraveltext) = ax;
+}
+
+void DreamGenContext::loadintotemp() {
+ STACK_CHECK;
+ ds = cs;
+ standardload();
+ data.word(kTempgraphics) = ax;
+}
+
+void DreamGenContext::loadintotemp2() {
+ STACK_CHECK;
+ ds = cs;
+ standardload();
+ data.word(kTempgraphics2) = ax;
+}
+
+void DreamGenContext::loadintotemp3() {
+ STACK_CHECK;
+ ds = cs;
+ standardload();
+ data.word(kTempgraphics3) = ax;
+}
+
+void DreamGenContext::loadtempcharset() {
+ STACK_CHECK;
+ standardload();
+ data.word(kTempcharset) = ax;
+}
+
+void DreamGenContext::standardload() {
+ STACK_CHECK;
+ openfile();
+ readheader();
+ bx = es.word(di);
+ push(bx);
+ cl = 4;
+ _shr(bx, cl);
+ allocatemem();
+ ds = ax;
+ cx = pop();
+ push(ax);
+ dx = 0;
+ readfromfile();
+ closefile();
+ ax = pop();
+}
+
+void DreamGenContext::loadtemptext() {
+ STACK_CHECK;
+ standardload();
+ data.word(kTextfile1) = ax;
+}
+
+void DreamGenContext::loadroom() {
+ STACK_CHECK;
+ data.byte(kRoomloaded) = 1;
+ data.word(kTimecount) = 0;
+ data.word(kMaintimer) = 0;
+ data.word(kMapoffsetx) = 104;
+ data.word(kMapoffsety) = 38;
+ data.word(kTextaddressx) = 13;
+ data.word(kTextaddressy) = 182;
+ data.byte(kTextlen) = 240;
+ al = data.byte(kNewlocation);
+ data.byte(kLocation) = al;
+ getroomdata();
+ startloading();
+ loadroomssample();
+ switchryanon();
+ drawflags();
+ getdimension();
+}
+
+void DreamGenContext::loadroomssample() {
+ STACK_CHECK;
+ al = data.byte(kRoomssample);
+ _cmp(al, 255);
+ if (flags.z())
+ return /* (loadedalready) */;
+ _cmp(al, data.byte(kCurrentsample));
+ if (flags.z())
+ return /* (loadedalready) */;
+ data.byte(kCurrentsample) = al;
+ al = data.byte(kCurrentsample);
+ cl = '0';
+ twodigitnum();
+ di = 1896;
+ _xchg(al, ah);
+ cs.word(di+10) = ax;
+ dx = di;
+ loadsecondsample();
+}
+
+void DreamGenContext::getridofreels() {
+ STACK_CHECK;
+ _cmp(data.byte(kRoomloaded), 0);
+ if (flags.z())
+ return /* (dontgetrid) */;
+ es = data.word(kReel1);
+ deallocatemem();
+ es = data.word(kReel2);
+ deallocatemem();
+ es = data.word(kReel3);
+ deallocatemem();
+}
+
+void DreamGenContext::getridofall() {
+ STACK_CHECK;
+ es = data.word(kBackdrop);
+ deallocatemem();
+ es = data.word(kSetframes);
+ deallocatemem();
+ es = data.word(kReel1);
+ deallocatemem();
+ es = data.word(kReel2);
+ deallocatemem();
+ es = data.word(kReel3);
+ deallocatemem();
+ es = data.word(kReels);
+ deallocatemem();
+ es = data.word(kPeople);
+ deallocatemem();
+ es = data.word(kSetdesc);
+ deallocatemem();
+ es = data.word(kBlockdesc);
+ deallocatemem();
+ es = data.word(kRoomdesc);
+ deallocatemem();
+ es = data.word(kFreeframes);
+ deallocatemem();
+ es = data.word(kFreedesc);
+ deallocatemem();
+}
+
+void DreamGenContext::restorereels() {
+ STACK_CHECK;
+ _cmp(data.byte(kRoomloaded), 0);
+ if (flags.z())
+ return /* (dontrestore) */;
+ al = data.byte(kReallocation);
+ getroomdata();
+ dx = bx;
+ openfile();
+ readheader();
+ dontloadseg();
+ dontloadseg();
+ dontloadseg();
+ dontloadseg();
+ allocateload();
+ data.word(kReel1) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel2) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel3) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ closefile();
+}
+
+void DreamGenContext::restoreall() {
+ STACK_CHECK;
+ al = data.byte(kLocation);
+ getroomdata();
+ dx = bx;
+ openfile();
+ readheader();
+ allocateload();
+ ds = ax;
+ data.word(kBackdrop) = ax;
+ dx = (0);
+ loadseg();
+ ds = data.word(kWorkspace);
+ dx = (0);
+ cx = 132*66;
+ al = 0;
+ fillspace();
+ loadseg();
+ sortoutmap();
+ allocateload();
+ data.word(kSetframes) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ dontloadseg();
+ allocateload();
+ data.word(kReel1) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel2) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel3) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReels) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kPeople) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kSetdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kBlockdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kRoomdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kFreeframes) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ dontloadseg();
+ allocateload();
+ data.word(kFreedesc) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ closefile();
+ setallchanges();
+}
+
+void DreamGenContext::sortoutmap() {
+ STACK_CHECK;
+ push(es);
+ push(di);
+ ds = data.word(kWorkspace);
+ si = 0;
+ es = data.word(kMapdata);
+ di = 0;
+ cx = (60);
+blimey:
+ push(cx);
+ push(si);
+ cx = (66);
+ _movsb(cx, true);
+ si = pop();
+ cx = pop();
+ _add(si, 132);
+ if (--cx)
+ goto blimey;
+ di = pop();
+ es = pop();
+}
+
+void DreamGenContext::startloading() {
+ STACK_CHECK;
+ data.byte(kCombatcount) = 0;
+ al = cs.byte(bx+13);
+ data.byte(kRoomssample) = al;
+ al = cs.byte(bx+15);
+ data.byte(kMapx) = al;
+ al = cs.byte(bx+16);
+ data.byte(kMapy) = al;
+ al = cs.byte(bx+20);
+ data.byte(kLiftflag) = al;
+ al = cs.byte(bx+21);
+ data.byte(kManspath) = al;
+ data.byte(kDestination) = al;
+ data.byte(kFinaldest) = al;
+ al = cs.byte(bx+22);
+ data.byte(kFacing) = al;
+ data.byte(kTurntoface) = al;
+ al = cs.byte(bx+23);
+ data.byte(kCounttoopen) = al;
+ al = cs.byte(bx+24);
+ data.byte(kLiftpath) = al;
+ al = cs.byte(bx+25);
+ data.byte(kDoorpath) = al;
+ data.byte(kLastweapon) = -1;
+ al = cs.byte(bx+27);
+ push(ax);
+ al = cs.byte(bx+31);
+ ah = data.byte(kReallocation);
+ data.byte(kReallocation) = al;
+ dx = bx;
+ openfile();
+ readheader();
+ allocateload();
+ ds = ax;
+ data.word(kBackdrop) = ax;
+ dx = (0);
+ loadseg();
+ ds = data.word(kWorkspace);
+ dx = (0);
+ cx = 132*66;
+ al = 0;
+ fillspace();
+ loadseg();
+ sortoutmap();
+ allocateload();
+ data.word(kSetframes) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ ds = data.word(kSetdat);
+ dx = 0;
+ cx = (64*128);
+ al = 255;
+ fillspace();
+ loadseg();
+ allocateload();
+ data.word(kReel1) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel2) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel3) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReels) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kPeople) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kSetdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kBlockdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kRoomdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kFreeframes) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ ds = data.word(kFreedat);
+ dx = 0;
+ cx = (16*80);
+ al = 255;
+ fillspace();
+ loadseg();
+ allocateload();
+ data.word(kFreedesc) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ closefile();
+ findroominloc();
+ deletetaken();
+ setallchanges();
+ autoappear();
+ al = data.byte(kNewlocation);
+ getroomdata();
+ data.byte(kLastweapon) = -1;
+ data.byte(kMandead) = 0;
+ data.word(kLookcounter) = 160;
+ data.byte(kNewlocation) = 255;
+ data.byte(kLinepointer) = 254;
+ ax = pop();
+ _cmp(al, 255);
+ if (flags.z())
+ goto dontwalkin;
+ data.byte(kManspath) = al;
+ push(bx);
+ autosetwalk();
+ bx = pop();
+dontwalkin:
+ findxyfrompath();
+}
+
+void DreamGenContext::disablepath() {
+ STACK_CHECK;
+ push(cx);
+ _xchg(al, ah);
+ cx = -6;
+looky2:
+ _add(cx, 6);
+ _sub(al, 10);
+ if (!flags.c())
+ goto looky2;
+ al = ah;
+ _dec(cx);
+lookx2:
+ _inc(cx);
+ _sub(al, 11);
+ if (!flags.c())
+ goto lookx2;
+ al = cl;
+ ah = 0;
+ cx = 144;
+ _mul(cx);
+ es = data.word(kReels);
+ bx = (0);
+ _add(bx, ax);
+ ax = pop();
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ al = 0;
+ es.byte(bx+6) = al;
+}
+
+void DreamGenContext::findxyfrompath() {
+ STACK_CHECK;
+ getroomspaths();
+ al = data.byte(kManspath);
+ ah = 0;
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(ax, ax);
+ _add(bx, ax);
+ ax = es.word(bx);
+ _sub(al, 12);
+ _sub(ah, 12);
+ data.byte(kRyanx) = al;
+ data.byte(kRyany) = ah;
+}
+
+void DreamGenContext::findroominloc() {
+ STACK_CHECK;
+ al = data.byte(kMapy);
+ cx = -6;
+looky:
+ _add(cx, 6);
+ _sub(al, 10);
+ if (!flags.c())
+ goto looky;
+ al = data.byte(kMapx);
+ _dec(cx);
+lookx:
+ _inc(cx);
+ _sub(al, 11);
+ if (!flags.c())
+ goto lookx;
+ data.byte(kRoomnum) = cl;
+}
+
+void DreamGenContext::getroomdata() {
+ STACK_CHECK;
+ ah = 0;
+ cx = 32;
+ _mul(cx);
+ bx = 6187;
+ _add(bx, ax);
+}
+
+void DreamGenContext::readheader() {
+ STACK_CHECK;
+ ds = cs;
+ dx = 6091;
+ cx = (6187-6091);
+ readfromfile();
+ es = cs;
+ di = 6141;
+}
+
+void DreamGenContext::allocateload() {
+ STACK_CHECK;
+ push(es);
+ push(di);
+ bx = es.word(di);
+ cl = 4;
+ _shr(bx, cl);
+ allocatemem();
+ di = pop();
+ es = pop();
+}
+
+void DreamGenContext::fillspace() {
+ STACK_CHECK;
+ push(es);
+ push(ds);
+ push(dx);
+ push(di);
+ push(bx);
+ di = dx;
+ es = ds;
+ _stosb(cx, true);
+ bx = pop();
+ di = pop();
+ dx = pop();
+ ds = pop();
+ es = pop();
+}
+
+void DreamGenContext::getridoftemp() {
+ STACK_CHECK;
+ es = data.word(kTempgraphics);
+ deallocatemem();
+}
+
+void DreamGenContext::getridoftemptext() {
+ STACK_CHECK;
+ es = data.word(kTextfile1);
+ deallocatemem();
+}
+
+void DreamGenContext::getridoftemp2() {
+ STACK_CHECK;
+ es = data.word(kTempgraphics2);
+ deallocatemem();
+}
+
+void DreamGenContext::getridoftemp3() {
+ STACK_CHECK;
+ es = data.word(kTempgraphics3);
+ deallocatemem();
+}
+
+void DreamGenContext::getridoftempcharset() {
+ STACK_CHECK;
+ es = data.word(kTempcharset);
+ deallocatemem();
+}
+
+void DreamGenContext::getridoftempsp() {
+ STACK_CHECK;
+ es = data.word(kTempsprites);
+ deallocatemem();
+}
+
+void DreamGenContext::readsetdata() {
+ STACK_CHECK;
+ dx = 1857;
+ standardload();
+ data.word(kCharset1) = ax;
+ dx = 1922;
+ standardload();
+ data.word(kIcons1) = ax;
+ dx = 1935;
+ standardload();
+ data.word(kIcons2) = ax;
+ dx = 1819;
+ standardload();
+ data.word(kMainsprites) = ax;
+ dx = 2221;
+ standardload();
+ data.word(kPuzzletext) = ax;
+ dx = 2273;
+ standardload();
+ data.word(kCommandtext) = ax;
+ ax = data.word(kCharset1);
+ data.word(kCurrentset) = ax;
+ _cmp(data.byte(kSoundint), 255);
+ if (flags.z())
+ return /* (novolumeload) */;
+ dx = 2286;
+ openfile();
+ cx = 2048-256;
+ ds = data.word(kSoundbuffer);
+ dx = 16384;
+ readfromfile();
+ closefile();
+}
+
+void DreamGenContext::makename() {
+ STACK_CHECK;
+ si = dx;
+ di = 6061;
+transfer:
+ al = cs.byte(si);
+ cs.byte(di) = al;
+ _inc(si);
+ _inc(di);
+ _cmp(al, 0);
+ if (!flags.z())
+ goto transfer;
+ dx = 6059;
+}
+
+void DreamGenContext::dreamweb() {
+ STACK_CHECK;
+ seecommandtail();
+ checkbasemem();
+ soundstartup();
+ setkeyboardint();
+ setupemm();
+ allocatebuffers();
+ setmouse();
+ fadedos();
+ gettime();
+ clearbuffers();
+ clearpalette();
+ set16colpalette();
+ readsetdata();
+ data.byte(kWongame) = 0;
+ dx = 1909;
+ loadsample();
+ setsoundoff();
+ scanfornames();
+ _cmp(al, 0);
+ if (!flags.z())
+ goto dodecisions;
+ setmode();
+ loadpalfromiff();
+ titles();
+ credits();
+ goto playgame;
+dodecisions:
+ cls();
+ setmode();
+ decide();
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (exitgame) */;
+ _cmp(data.byte(kGetback), 4);
+ if (flags.z())
+ goto mainloop;
+ titles();
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (exitgame) */;
+ credits();
+playgame:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (exitgame) */;
+ clearchanges();
+ setmode();
+ loadpalfromiff();
+ data.byte(kLocation) = 255;
+ data.byte(kRoomafterdream) = 1;
+ data.byte(kNewlocation) = 35;
+ data.byte(kVolume) = 7;
+ loadroom();
+ clearsprites();
+ initman();
+ entrytexts();
+ entryanims();
+ data.byte(kDestpos) = 3;
+ initialinv();
+ data.byte(kLastflag) = 32;
+ startup1();
+ data.byte(kVolumeto) = 0;
+ data.byte(kVolumedirection) = -1;
+ data.byte(kCommandtype) = 255;
+ goto mainloop;
+loadnew:
+ clearbeforeload();
+ loadroom();
+ clearsprites();
+ initman();
+ entrytexts();
+ entryanims();
+ data.byte(kNewlocation) = 255;
+ startup();
+ data.byte(kCommandtype) = 255;
+ worktoscreenm();
+ goto mainloop;
+ data.byte(kNewlocation) = 255;
+ clearsprites();
+ initman();
+ startup();
+ data.byte(kCommandtype) = 255;
+mainloop:
+ _cmp(data.byte(kQuitrequested), 0);
+ if (!flags.z())
+ return /* (exitgame) */;
+ screenupdate();
+ _cmp(data.byte(kWongame), 0);
+ if (!flags.z())
+ goto endofgame;
+ _cmp(data.byte(kMandead), 1);
+ if (flags.z())
+ goto gameover;
+ _cmp(data.byte(kMandead), 2);
+ if (flags.z())
+ goto gameover;
+ _cmp(data.word(kWatchingtime), 0);
+ if (flags.z())
+ goto notwatching;
+ al = data.byte(kFinaldest);
+ _cmp(al, data.byte(kManspath));
+ if (!flags.z())
+ goto mainloop;
+ _dec(data.word(kWatchingtime));
+ if (!flags.z())
+ goto mainloop;
+notwatching:
+ _cmp(data.byte(kMandead), 4);
+ if (flags.z())
+ goto gameover;
+ _cmp(data.byte(kNewlocation), 255);
+ if (!flags.z())
+ goto loadnew;
+ goto mainloop;
+gameover:
+ clearbeforeload();
+ showgun();
+ fadescreendown();
+ cx = 100;
+ hangon();
+ goto dodecisions;
+endofgame:
+ clearbeforeload();
+ fadescreendowns();
+ cx = 200;
+ hangon();
+ endgame();
+ { quickquit2(); return; };
+}
+
+
+
+void DreamGenContext::__start() {
+ static const uint8 src[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x14, 0x00, 0x02, 0x00, 0x01, 0x01, 0x37,
+ 0x00, 0x00, 0x00, 0x32, 0x14, 0x00, 0x18, 0x16, 0x00, 0x4a, 0x00, 0x01, 0x00, 0x00, 0x18, 0x21,
+ 0x0a, 0x4b, 0x00, 0x01, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x1b, 0x00, 0x02, 0x00, 0x02, 0x01, 0x2c,
+ 0x00, 0x60, 0x00, 0x03, 0x00, 0x04, 0x01, 0x2c, 0x00, 0x76, 0x00, 0x02, 0x00, 0x05, 0x01, 0x2c,
+ 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x16, 0x14, 0x35, 0x00, 0x03, 0x00, 0x00, 0x05, 0x16,
+ 0x14, 0x28, 0x00, 0x01, 0x00, 0x02, 0x05, 0x16, 0x14, 0x32, 0x00, 0x01, 0x00, 0x03, 0x02, 0x0b,
+ 0x0a, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x02, 0x0b, 0x0a, 0xb6, 0x00, 0x02, 0x00, 0x01, 0x08, 0x0b,
+ 0x0a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x17, 0x00, 0x32, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1c, 0x0b,
+ 0x14, 0xfa, 0x00, 0x04, 0x00, 0x00, 0x17, 0x00, 0x32, 0x2b, 0x00, 0x02, 0x00, 0x08, 0x17, 0x0b,
+ 0x28, 0x82, 0x00, 0x02, 0x00, 0x01, 0x17, 0x16, 0x28, 0x7a, 0x00, 0x02, 0x00, 0x02, 0x17, 0x16,
+ 0x28, 0x69, 0x00, 0x02, 0x00, 0x03, 0x17, 0x16, 0x28, 0x51, 0x00, 0x02, 0x00, 0x04, 0x17, 0x0b,
+ 0x28, 0x87, 0x00, 0x02, 0x00, 0x05, 0x17, 0x16, 0x28, 0x91, 0x00, 0x02, 0x00, 0x06, 0x04, 0x16,
+ 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x2d, 0x16, 0x1e, 0xc8, 0x00, 0x00, 0x00, 0x14, 0x2d, 0x16,
+ 0x1e, 0x27, 0x00, 0x02, 0x00, 0x00, 0x2d, 0x16, 0x1e, 0x19, 0x00, 0x02, 0x00, 0x00, 0x08, 0x16,
+ 0x28, 0x20, 0x00, 0x02, 0x00, 0x00, 0x07, 0x0b, 0x14, 0x40, 0x00, 0x02, 0x00, 0x00, 0x16, 0x16,
+ 0x14, 0x52, 0x00, 0x02, 0x00, 0x00, 0x1b, 0x0b, 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x00,
+ 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0e, 0x21, 0x28, 0x15, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x0b,
+ 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x16, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00,
+ 0x32, 0x04, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, 0x1e, 0x79, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16,
+ 0x1e, 0x00, 0x00, 0x14, 0x00, 0x00, 0x34, 0x16, 0x1e, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16,
+ 0x1e, 0xe9, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, 0x28, 0x68, 0x00, 0x37, 0x00, 0x00, 0x35, 0x21,
+ 0x00, 0x63, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, 0x28, 0x00, 0x00, 0x03, 0x00, 0x00, 0x32, 0x16,
+ 0x1e, 0xa2, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16, 0x1e, 0x39, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16,
+ 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x36, 0x00, 0x00, 0x48, 0x00, 0x03, 0x00, 0x00, 0x37, 0x2c,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x0e, 0x16,
+ 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x0e, 0x16, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x0a, 0x16,
+ 0x1e, 0xae, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x16, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0b,
+ 0x14, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0b, 0x0b, 0x1e, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0b, 0x16,
+ 0x14, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0e, 0x21, 0x28, 0x00, 0x00, 0x32, 0x14, 0x00, 0xff, 0x7c,
+ 0xc0, 0x80, 0xc0, 0x1c, 0xc0, 0x20, 0xc0, 0x00, 0xc1, 0x10, 0xc0, 0x18, 0xc0, 0xf4, 0xc0, 0x0c,
+ 0xc0, 0x24, 0xc0, 0x28, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x54, 0xc0, 0x78, 0xc0, 0x50, 0xc0, 0x74,
+ 0xc0, 0x34, 0xc0, 0x38, 0xc0, 0x40, 0xc0, 0x44, 0xc0, 0x48, 0xc0, 0x3c, 0xc0, 0x14, 0xc0, 0x88,
+ 0xc0, 0x8c, 0xc0, 0x90, 0xc0, 0x70, 0xc0, 0xfc, 0xc0, 0x6c, 0xc0, 0x58, 0xc0, 0x68, 0xc0, 0x04,
+ 0xc1, 0x64, 0xc0, 0x60, 0xc0, 0x5c, 0xc0, 0x94, 0xc0, 0x04, 0xc0, 0xa4, 0xc0, 0x9c, 0xc0, 0xa0,
+ 0xc0, 0xa8, 0xc0, 0xac, 0xc0, 0x98, 0xc0, 0xb0, 0xc0, 0xb4, 0xc0, 0xc8, 0xc0, 0xcc, 0xc0, 0xd4,
+ 0xc0, 0xdc, 0xc0, 0xd8, 0xc0, 0x00, 0xc0, 0x08, 0xc0, 0x84, 0xc0, 0x84, 0xc0, 0x84, 0xc0, 0x84,
+ 0xc0, 0x00, 0x3c, 0x21, 0x47, 0x0b, 0x52, 0x16, 0x5d, 0x01, 0x2c, 0x0a, 0x10, 0x04, 0x0b, 0x1e,
+ 0x0e, 0x04, 0x16, 0x1e, 0x0e, 0x03, 0x21, 0x0a, 0x0e, 0x0a, 0x21, 0x1e, 0x0e, 0x0a, 0x16, 0x1e,
+ 0x18, 0x09, 0x16, 0x0a, 0x0e, 0x02, 0x21, 0x00, 0x0e, 0x02, 0x16, 0x00, 0x0e, 0x06, 0x0b, 0x1e,
+ 0x0e, 0x07, 0x0b, 0x14, 0x12, 0x07, 0x00, 0x14, 0x12, 0x07, 0x00, 0x1e, 0x12, 0x37, 0x2c, 0x00,
+ 0x0e, 0x05, 0x16, 0x1e, 0x0e, 0x08, 0x00, 0x0a, 0x12, 0x08, 0x0b, 0x0a, 0x12, 0x08, 0x16, 0x0a,
+ 0x12, 0x08, 0x21, 0x0a, 0x12, 0x08, 0x21, 0x14, 0x12, 0x08, 0x21, 0x1e, 0x12, 0x08, 0x21, 0x28,
+ 0x12, 0x08, 0x16, 0x28, 0x12, 0x08, 0x0b, 0x28, 0x12, 0x15, 0x2c, 0x14, 0x12, 0xff, 0x2e, 0x05,
+ 0x2f, 0x05, 0x33, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x46, 0x05, 0x2e, 0x05, 0x4d, 0x05,
+ 0x5d, 0x05, 0x64, 0x05, 0x68, 0x05, 0x6c, 0x05, 0x70, 0x05, 0x7d, 0x05, 0x2e, 0x05, 0x2e, 0x05,
+ 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x9f, 0x05, 0x2e, 0x05, 0xb5, 0x05, 0xd4, 0x05, 0x2e, 0x05,
+ 0xe1, 0x05, 0xf7, 0x05, 0x0d, 0x06, 0x26, 0x06, 0x39, 0x06, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05,
+ 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05,
+ 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x49, 0x06, 0x50, 0x06, 0x75, 0x06, 0x2e, 0x05,
+ 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x82, 0x06, 0x86, 0x06, 0x2e, 0x05, 0x8d, 0x06, 0xff, 0x0f,
+ 0x01, 0x01, 0xff, 0x0c, 0x05, 0x00, 0x0d, 0x15, 0x00, 0x0f, 0x23, 0x00, 0x11, 0x32, 0x00, 0x12,
+ 0x67, 0x00, 0x13, 0x6c, 0x00, 0xff, 0x12, 0x13, 0x00, 0x13, 0x17, 0x00, 0xff, 0x0c, 0x33, 0x00,
+ 0x0d, 0x35, 0x00, 0x0e, 0x0e, 0x00, 0x0f, 0x14, 0x00, 0x00, 0x4e, 0x00, 0xff, 0x0c, 0x77, 0x00,
+ 0x0c, 0x91, 0x00, 0xff, 0x0d, 0x10, 0x00, 0xff, 0x0d, 0x14, 0x00, 0xff, 0x0e, 0x10, 0x00, 0xff,
+ 0x0f, 0x04, 0x00, 0x10, 0x08, 0x00, 0x11, 0x86, 0x00, 0x12, 0x99, 0x00, 0xff, 0x0d, 0x6c, 0x00,
+ 0x0f, 0x46, 0x01, 0x0f, 0x4b, 0x01, 0x0f, 0x50, 0x01, 0x0f, 0x56, 0x01, 0x0f, 0x5c, 0x01, 0x0f,
+ 0x62, 0x01, 0x12, 0x9f, 0x00, 0x12, 0xb2, 0x00, 0x93, 0xd9, 0x00, 0x54, 0xe4, 0x00, 0xff, 0x0d,
+ 0x14, 0x00, 0x0d, 0x15, 0x00, 0x0f, 0x22, 0x00, 0x0d, 0x34, 0x00, 0x0d, 0x37, 0x00, 0x19, 0x39,
+ 0x00, 0x15, 0x49, 0x00, 0xff, 0x0d, 0xc4, 0x00, 0x0d, 0xea, 0x00, 0x0d, 0x9c, 0x00, 0x0e, 0x81,
+ 0x00, 0x0d, 0x7c, 0x00, 0x0f, 0xa2, 0x00, 0x0f, 0xc8, 0x00, 0x0f, 0xef, 0x00, 0x11, 0x63, 0x00,
+ 0x0c, 0x34, 0x00, 0xff, 0x0f, 0x38, 0x00, 0x10, 0x40, 0x00, 0x13, 0x16, 0x00, 0x14, 0x21, 0x00,
+ 0xff, 0x14, 0x0b, 0x00, 0x14, 0x0f, 0x00, 0x0f, 0x1c, 0x00, 0x0d, 0x50, 0x00, 0x15, 0x52, 0x00,
+ 0x93, 0x57, 0x00, 0x57, 0x80, 0x00, 0xff, 0x0c, 0x0d, 0x00, 0x0e, 0x27, 0x00, 0x0c, 0x43, 0x00,
+ 0x0c, 0x4b, 0x00, 0x0c, 0x53, 0x00, 0x0c, 0x5b, 0x00, 0x0f, 0x66, 0x00, 0xff, 0x16, 0x24, 0x00,
+ 0x0d, 0x7d, 0x00, 0x12, 0x58, 0x00, 0x0f, 0x6b, 0x00, 0x0e, 0x7f, 0x00, 0x0e, 0x9a, 0x00, 0x93,
+ 0xaa, 0x00, 0x57, 0xe8, 0x00, 0xff, 0x15, 0x10, 0x00, 0x15, 0x48, 0x00, 0x15, 0xcd, 0x00, 0x16,
+ 0x3f, 0x00, 0x97, 0x63, 0x00, 0x58, 0x9e, 0x00, 0xff, 0x0d, 0x15, 0x00, 0x0e, 0x18, 0x00, 0x93,
+ 0x32, 0x00, 0x57, 0x4b, 0x00, 0x18, 0x80, 0x00, 0xff, 0x53, 0x2e, 0x00, 0x10, 0xa7, 0x00, 0xff,
+ 0x10, 0x13, 0x00, 0x0e, 0x24, 0x00, 0x10, 0x32, 0x00, 0x0e, 0x41, 0x00, 0x10, 0x51, 0x00, 0x0e,
+ 0x60, 0x00, 0x10, 0x72, 0x00, 0x0e, 0x81, 0x00, 0x10, 0x93, 0x00, 0x0e, 0xa2, 0x00, 0x10, 0xb1,
+ 0x00, 0x0e, 0xbf, 0x00, 0xff, 0x0d, 0x30, 0x00, 0x0e, 0x29, 0x00, 0x0f, 0x4e, 0x00, 0x10, 0x5c,
+ 0x00, 0xff, 0x10, 0x73, 0x00, 0xff, 0x15, 0x67, 0x00, 0x14, 0xc7, 0x00, 0xff, 0x11, 0x35, 0x00,
+ 0x11, 0x36, 0x00, 0x11, 0x37, 0x00, 0x11, 0x38, 0x00, 0x11, 0x39, 0x00, 0x11, 0x3a, 0x00, 0x11,
+ 0x3b, 0x00, 0x11, 0x3d, 0x00, 0x11, 0x3f, 0x00, 0x11, 0x40, 0x00, 0x11, 0x41, 0x00, 0xff, 0x9c,
+ 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c,
+ 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d,
+ 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c,
+ 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c,
+ 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d,
+ 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c,
+ 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9c, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x53, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
+ 0x2e, 0x53, 0x30, 0x32, 0x00, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x2e, 0x44, 0x41, 0x54,
+ 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x43, 0x30, 0x30, 0x00, 0x44, 0x52,
+ 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x43, 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x43, 0x30, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
+ 0x2e, 0x56, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x56, 0x39,
+ 0x39, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x30, 0x00, 0x44,
+ 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41,
+ 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
+ 0x42, 0x2e, 0x47, 0x30, 0x38, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47,
+ 0x30, 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x37, 0x00,
+ 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x34, 0x00, 0x44, 0x52, 0x45,
+ 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
+ 0x45, 0x42, 0x2e, 0x47, 0x30, 0x36, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
+ 0x47, 0x31, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x30, 0x31,
+ 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x30, 0x32, 0x00, 0x44, 0x52,
+ 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x31, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x54, 0x31, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
+ 0x2e, 0x54, 0x31, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x31,
+ 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x32, 0x30, 0x00, 0x44,
+ 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x32, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41,
+ 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x32, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
+ 0x42, 0x2e, 0x54, 0x32, 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54,
+ 0x32, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x35, 0x30, 0x00,
+ 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x35, 0x31, 0x00, 0x44, 0x52, 0x45,
+ 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x38, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
+ 0x45, 0x42, 0x2e, 0x54, 0x38, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
+ 0x54, 0x38, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x38, 0x33,
+ 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x38, 0x34, 0x00, 0x44, 0x52,
+ 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x56, 0x4f, 0x4c, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x39, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
+ 0x2e, 0x47, 0x31, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31,
+ 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x32, 0x00, 0x44,
+ 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x33, 0x00, 0x44, 0x52, 0x45, 0x41,
+ 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
+ 0x42, 0x2e, 0x49, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49,
+ 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x32, 0x00,
+ 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x33, 0x00, 0x44, 0x52, 0x45,
+ 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
+ 0x45, 0x42, 0x2e, 0x49, 0x30, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
+ 0x49, 0x30, 0x36, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x37,
+ 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x50, 0x41, 0x4c, 0x00, 0x11, 0x01,
+ 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x44, 0xc3, 0x04, 0x01, 0x2c, 0x01, 0x00, 0x00, 0x2c, 0x00,
+ 0x80, 0xc5, 0xd2, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x2c, 0x00, 0xdc, 0xc3, 0x90, 0x00, 0xb0, 0x00,
+ 0x40, 0x00, 0x60, 0x00, 0x80, 0xc3, 0x00, 0x00, 0x32, 0x00, 0x32, 0x00, 0xc8, 0x00, 0x84, 0xc3,
+ 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01,
+ 0x9d, 0x00, 0xc6, 0x00, 0x44, 0xc3, 0xff, 0x00, 0x26, 0x01, 0x00, 0x00, 0x18, 0x00, 0xc8, 0xc3,
+ 0xf7, 0x00, 0x2d, 0x01, 0x28, 0x00, 0x38, 0x00, 0x48, 0xc3, 0x50, 0x00, 0x00, 0x01, 0x9e, 0x00,
+ 0xca, 0x00, 0xe0, 0xc3, 0x50, 0x00, 0x2c, 0x01, 0x3a, 0x00, 0x92, 0x00, 0x98, 0xc3, 0x00, 0x00,
+ 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00,
+ 0xc6, 0x00, 0x44, 0xc3, 0xf7, 0x00, 0x2d, 0x01, 0x28, 0x00, 0x38, 0x00, 0x48, 0xc3, 0x50, 0x00,
+ 0x2c, 0x01, 0x3a, 0x00, 0x92, 0x00, 0xbc, 0xc6, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
+ 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0xf0, 0x00,
+ 0x22, 0x01, 0x02, 0x00, 0x2c, 0x00, 0x94, 0xc4, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
+ 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0x00, 0x00,
+ 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0xee, 0x00, 0x02, 0x01, 0x04, 0x00,
+ 0x2c, 0x00, 0xc8, 0xc4, 0x68, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x2c, 0x00, 0xcc, 0xc4, 0x18, 0x01,
+ 0x34, 0x01, 0x04, 0x00, 0x2c, 0x00, 0xb0, 0xc4, 0x68, 0x00, 0xd8, 0x00, 0x8a, 0x00, 0xc0, 0x00,
+ 0xd0, 0xc4, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0x00, 0x00, 0x40, 0x01,
+ 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x45, 0x58, 0x49, 0x54, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x48, 0x45, 0x4c, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x49, 0x53, 0x54,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x41, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x4c, 0x4f, 0x47, 0x4f, 0x4e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4b, 0x45, 0x59, 0x53, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00,
+ 0x42, 0x4c, 0x41, 0x43, 0x4b, 0x44, 0x52, 0x41, 0x47, 0x4f, 0x4e, 0x20, 0x52, 0x59, 0x41, 0x4e,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x48, 0x45, 0x4e, 0x44, 0x52, 0x49,
+ 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x55, 0x49, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x00, 0x00, 0x00, 0x53, 0x45, 0x50, 0x54, 0x49, 0x4d, 0x55, 0x53, 0x20, 0x20, 0x20, 0x20,
+ 0x42, 0x45, 0x43, 0x4b, 0x45, 0x54, 0x54, 0x20, 0x20, 0x20, 0x20, 0x00, 0xff, 0xff, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x22, 0x52, 0x4f, 0x4f,
+ 0x54, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x4e, 0x45, 0x54, 0x57, 0xe8, 0xc4, 0x45, 0x4c,
+ 0x56, 0x41, 0x8c, 0xc6, 0x45, 0x4c, 0x56, 0x42, 0x9c, 0xc6, 0x45, 0x4c, 0x56, 0x43, 0x94, 0xc6,
+ 0x45, 0x4c, 0x56, 0x45, 0x98, 0xc6, 0x45, 0x4c, 0x56, 0x46, 0xa0, 0xc6, 0x43, 0x47, 0x41, 0x54,
+ 0x30, 0xc7, 0x52, 0x45, 0x4d, 0x4f, 0xa8, 0xc6, 0x42, 0x55, 0x54, 0x41, 0x3c, 0xc7, 0x43, 0x42,
+ 0x4f, 0x58, 0x44, 0xc7, 0x4c, 0x49, 0x54, 0x45, 0x5c, 0xc6, 0x50, 0x4c, 0x41, 0x54, 0x40, 0xc7,
+ 0x4c, 0x49, 0x46, 0x54, 0x7c, 0xc6, 0x57, 0x49, 0x52, 0x45, 0x84, 0xc6, 0x48, 0x4e, 0x44, 0x4c,
+ 0x88, 0xc6, 0x48, 0x41, 0x43, 0x48, 0x80, 0xc6, 0x44, 0x4f, 0x4f, 0x52, 0xb4, 0xc6, 0x43, 0x53,
+ 0x48, 0x52, 0x70, 0xc6, 0x47, 0x55, 0x4e, 0x41, 0x34, 0xc7, 0x43, 0x52, 0x41, 0x41, 0x64, 0xc6,
+ 0x43, 0x52, 0x42, 0x42, 0x68, 0xc6, 0x43, 0x52, 0x43, 0x43, 0x6c, 0xc6, 0x53, 0x45, 0x41, 0x54,
+ 0xf8, 0xc5, 0x4d, 0x45, 0x4e, 0x55, 0x98, 0xc7, 0x43, 0x4f, 0x4f, 0x4b, 0xac, 0xc6, 0x45, 0x4c,
+ 0x43, 0x41, 0x4c, 0xc6, 0x45, 0x44, 0x43, 0x41, 0x50, 0xc6, 0x44, 0x44, 0x43, 0x41, 0x54, 0xc6,
+ 0x41, 0x4c, 0x54, 0x52, 0x04, 0xc6, 0x4c, 0x4f, 0x4b, 0x41, 0x3c, 0xc6, 0x4c, 0x4f, 0x4b, 0x42,
+ 0x40, 0xc6, 0x45, 0x4e, 0x54, 0x41, 0x10, 0xc6, 0x45, 0x4e, 0x54, 0x42, 0x24, 0xc6, 0x45, 0x4e,
+ 0x54, 0x45, 0x28, 0xc6, 0x45, 0x4e, 0x54, 0x43, 0x18, 0xc6, 0x45, 0x4e, 0x54, 0x44, 0x2c, 0xc6,
+ 0x45, 0x4e, 0x54, 0x48, 0x30, 0xc6, 0x57, 0x57, 0x41, 0x54, 0xf0, 0xc5, 0x50, 0x4f, 0x4f, 0x4c,
+ 0x58, 0xc6, 0x57, 0x53, 0x48, 0x44, 0xf4, 0xc5, 0x47, 0x52, 0x41, 0x46, 0x44, 0xc6, 0x54, 0x52,
+ 0x41, 0x50, 0x48, 0xc6, 0x43, 0x44, 0x50, 0x45, 0x28, 0xc7, 0x44, 0x4c, 0x4f, 0x4b, 0x08, 0xc6,
+ 0x48, 0x4f, 0x4c, 0x45, 0x00, 0xc6, 0x44, 0x52, 0x59, 0x52, 0x0c, 0xc6, 0x48, 0x4f, 0x4c, 0x59,
+ 0xfc, 0xc5, 0x57, 0x41, 0x4c, 0x4c, 0x2c, 0xc7, 0x42, 0x4f, 0x4f, 0x4b, 0x08, 0xc8, 0x41, 0x58,
+ 0x45, 0x44, 0xb0, 0xc6, 0x53, 0x48, 0x4c, 0x44, 0x38, 0xc7, 0x42, 0x43, 0x4e, 0x59, 0xe8, 0xc5,
+ 0x4c, 0x49, 0x44, 0x43, 0xe4, 0xc5, 0x4c, 0x49, 0x44, 0x55, 0xe0, 0xc5, 0x4c, 0x49, 0x44, 0x4f,
+ 0xec, 0xc5, 0x50, 0x49, 0x50, 0x45, 0xa8, 0xc5, 0x42, 0x41, 0x4c, 0x43, 0x20, 0xc6, 0x57, 0x49,
+ 0x4e, 0x44, 0x1c, 0xc6, 0x50, 0x41, 0x50, 0x52, 0xb4, 0xc7, 0x55, 0x57, 0x54, 0x41, 0xa0, 0xc5,
+ 0x55, 0x57, 0x54, 0x42, 0xa0, 0xc5, 0x53, 0x54, 0x41, 0x54, 0xd8, 0xc7, 0x54, 0x4c, 0x49, 0x44,
+ 0x9c, 0xc5, 0x53, 0x4c, 0x41, 0x42, 0xd8, 0xc5, 0x43, 0x41, 0x52, 0x54, 0xdc, 0xc5, 0x46, 0x43,
+ 0x41, 0x52, 0xac, 0xc5, 0x53, 0x4c, 0x42, 0x41, 0xc0, 0xc5, 0x53, 0x4c, 0x42, 0x42, 0xc4, 0xc5,
+ 0x53, 0x4c, 0x42, 0x43, 0xcc, 0xc5, 0x53, 0x4c, 0x42, 0x44, 0xc8, 0xc5, 0x53, 0x4c, 0x42, 0x45,
+ 0xd0, 0xc5, 0x53, 0x4c, 0x42, 0x46, 0xd4, 0xc5, 0x50, 0x4c, 0x49, 0x4e, 0xb0, 0xc5, 0x4c, 0x41,
+ 0x44, 0x44, 0xb8, 0xc5, 0x4c, 0x41, 0x44, 0x42, 0xbc, 0xc5, 0x47, 0x55, 0x4d, 0x41, 0xb4, 0xc5,
+ 0x53, 0x51, 0x45, 0x45, 0x88, 0xc5, 0x54, 0x41, 0x50, 0x50, 0x8c, 0xc5, 0x47, 0x55, 0x49, 0x54,
+ 0x90, 0xc5, 0x43, 0x4f, 0x4e, 0x54, 0x94, 0xc5, 0x42, 0x45, 0x4c, 0x4c, 0x98, 0xc5, 0x8c, 0x8c,
+ 0x8c, 0x8c, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x9d, 0x00, 0xb2, 0x00, 0x51, 0x00,
+ 0x5e, 0x00, 0x58, 0xc7, 0xb3, 0x00, 0xc8, 0x00, 0x51, 0x00, 0x5e, 0x00, 0x5c, 0xc7, 0xc9, 0x00,
+ 0xde, 0x00, 0x51, 0x00, 0x5e, 0x00, 0x60, 0xc7, 0x9d, 0x00, 0xb2, 0x00, 0x5f, 0x00, 0x70, 0x00,
+ 0x64, 0xc7, 0xb3, 0x00, 0xc8, 0x00, 0x5f, 0x00, 0x70, 0x00, 0x68, 0xc7, 0xc9, 0x00, 0xde, 0x00,
+ 0x5f, 0x00, 0x70, 0x00, 0x6c, 0xc7, 0x9d, 0x00, 0xb2, 0x00, 0x71, 0x00, 0x82, 0x00, 0x70, 0xc7,
+ 0xb3, 0x00, 0xc8, 0x00, 0x71, 0x00, 0x82, 0x00, 0x74, 0xc7, 0xc9, 0x00, 0xde, 0x00, 0x71, 0x00,
+ 0x82, 0x00, 0x78, 0xc7, 0x9d, 0x00, 0xb2, 0x00, 0x83, 0x00, 0x91, 0x00, 0x7c, 0xc7, 0xb3, 0x00,
+ 0xde, 0x00, 0x83, 0x00, 0x91, 0x00, 0x80, 0xc7, 0xdc, 0x00, 0xea, 0x00, 0x98, 0x00, 0xa6, 0x00,
+ 0x50, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0xae, 0x00,
+ 0xbc, 0x00, 0x84, 0x00, 0x94, 0x00, 0x50, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
+ 0xa0, 0xca, 0xff, 0xff, 0x18, 0x01, 0x40, 0x01, 0xa0, 0x00, 0xc8, 0x00, 0x50, 0xc7, 0x8f, 0x00,
+ 0x2c, 0x01, 0x06, 0x00, 0xc2, 0x00, 0xb8, 0xc7, 0x00, 0x00, 0x8f, 0x00, 0x06, 0x00, 0xc2, 0x00,
+ 0xc0, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x68, 0x00,
+ 0x80, 0x00, 0x3a, 0x00, 0x48, 0x00, 0xdc, 0xc7, 0x40, 0x00, 0x74, 0x00, 0x4c, 0x00, 0x6a, 0x00,
+ 0xe0, 0xc7, 0x74, 0x00, 0xa8, 0x00, 0x4c, 0x00, 0x6a, 0x00, 0xe4, 0xc7, 0x40, 0x00, 0x74, 0x00,
+ 0x6a, 0x00, 0x88, 0x00, 0xe8, 0xc7, 0x74, 0x00, 0xa8, 0x00, 0x6a, 0x00, 0x88, 0x00, 0xec, 0xc7,
+ 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0xba, 0x00, 0xca, 0x00,
+ 0x9d, 0x00, 0xad, 0x00, 0x1c, 0xc8, 0xf3, 0x00, 0x03, 0x01, 0x83, 0x00, 0x93, 0x00, 0x18, 0xc8,
+ 0x0c, 0x01, 0x1c, 0x01, 0xa8, 0x00, 0xb8, 0x00, 0x50, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
+ 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x77, 0x00, 0xae, 0x00, 0x52, 0x00, 0x80, 0x00, 0x34, 0xc8,
+ 0x46, 0x00, 0x89, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0x80, 0xc8, 0xbc, 0x00, 0xfa, 0x00, 0x44, 0x00,
+ 0x98, 0x00, 0x4c, 0xc8, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff,
+ 0xec, 0x00, 0xfc, 0x00, 0x70, 0x00, 0x80, 0x00, 0x48, 0xc8, 0xbc, 0x00, 0xfa, 0x00, 0x40, 0x00,
+ 0x98, 0x00, 0x58, 0xc8, 0x3e, 0x00, 0x98, 0x00, 0x38, 0x00, 0x85, 0x00, 0x74, 0xc8, 0x00, 0x00,
+ 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x77, 0x00, 0xae, 0x00, 0x52, 0x00,
+ 0x80, 0x00, 0x44, 0xc8, 0x46, 0x00, 0x8b, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0x50, 0xc8, 0xec, 0x00,
+ 0xfc, 0x00, 0x70, 0x00, 0x80, 0x00, 0x48, 0xc8, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
+ 0xa0, 0xca, 0xff, 0xff, 0xec, 0x00, 0xfc, 0x00, 0x70, 0x00, 0x80, 0x00, 0x48, 0xc8, 0xbc, 0x00,
+ 0xfa, 0x00, 0x40, 0x00, 0x98, 0x00, 0x54, 0xc8, 0x3e, 0x00, 0x98, 0x00, 0x38, 0x00, 0x85, 0x00,
+ 0x74, 0xc8, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x0d, 0x0a,
+ 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61,
+ 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x55, 0x6e, 0x61, 0x62, 0x6c, 0x65,
+ 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x20, 0x45, 0x78, 0x70,
+ 0x61, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2e, 0x0d, 0x0a, 0x0d,
+ 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68,
+ 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x53, 0x6f,
+ 0x75, 0x6e, 0x64, 0x20, 0x42, 0x6c, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x63, 0x61, 0x72, 0x64,
+ 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x74, 0x20, 0x61, 0x64,
+ 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x32, 0x32, 0x30, 0x20, 0x48, 0x65, 0x78, 0x2e, 0x0d, 0x0a,
+ 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20,
+ 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x4f,
+ 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x42, 0x61, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
+ 0x79, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d,
+ 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72,
+ 0x3a, 0x0d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x44, 0x65, 0x61, 0x6c, 0x6c, 0x6f,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2e, 0x0d,
+ 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62,
+ 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a,
+ 0x41, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x35, 0x39, 0x30, 0x4b, 0x20, 0x6f, 0x66,
+ 0x20, 0x62, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x69, 0x73, 0x20,
+ 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a,
+ 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61,
+ 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x20,
+ 0x42, 0x6c, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e,
+ 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x75, 0x70, 0x74, 0x20, 0x30, 0x0d,
+ 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62,
+ 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a,
+ 0x55, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
+ 0x20, 0x45, 0x4d, 0x4d, 0x20, 0x70, 0x61, 0x67, 0x65, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x24, 0x0d,
+ 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20,
+ 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x20,
+ 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x63, 0x0d, 0x0a, 0x0d, 0x0a, 0x24,
+ 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x66,
+ 0x6f, 0x72, 0x20, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x42, 0x6c, 0x61, 0x73, 0x74, 0x65, 0x72,
+ 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x0d,
+ 0x0a, 0x74, 0x68, 0x65, 0x20, 0x42, 0x4c, 0x41, 0x53, 0x54, 0x45, 0x52, 0x20, 0x65, 0x6e, 0x76,
+ 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
+ 0x65, 0x20, 0x28, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x41, 0x55, 0x54, 0x4f, 0x45,
+ 0x58, 0x45, 0x43, 0x2e, 0x42, 0x41, 0x54, 0x29, 0x0d, 0x0a, 0x0d, 0x0a, 0x49, 0x66, 0x20, 0x74,
+ 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64,
+ 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x49, 0x52, 0x51, 0x20, 0x37, 0x2c, 0x20, 0x44, 0x4d, 0x41,
+ 0x20, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x20, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62,
+ 0x61, 0x73, 0x65, 0x0d, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x32, 0x32, 0x30,
+ 0x68, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x2e, 0x0d, 0x0a,
+ 0x0d, 0x0a, 0x54, 0x6f, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f,
+ 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x73,
+ 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20,
+ 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x0d, 0x0a, 0x6f, 0x6e,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6e,
+ 0x65, 0x2e, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x0d,
+ 0x0a, 0x0d, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x20, 0x20, 0x20, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x20, 0x49, 0x37, 0x20, 0x41, 0x32, 0x32, 0x30, 0x20, 0x44, 0x31, 0x20, 0x20,
+ 0x20, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65,
+ 0x62, 0x20, 0x6f, 0x6e, 0x20, 0x49, 0x52, 0x51, 0x20, 0x37, 0x2c, 0x20, 0x44, 0x4d, 0x41, 0x0d,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x20, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x61,
+ 0x73, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x32, 0x32, 0x30, 0x68, 0x0d,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
+ 0x42, 0x20, 0x49, 0x35, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20,
+ 0x6f, 0x6e, 0x20, 0x49, 0x52, 0x51, 0x20, 0x35, 0x20, 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66,
+ 0x61, 0x75, 0x6c, 0x74, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20,
+ 0x32, 0x32, 0x30, 0x68, 0x2c, 0x20, 0x44, 0x4d, 0x41, 0x20, 0x31, 0x0d, 0x0a, 0x0d, 0x0a, 0x24,
+ 0x0d, 0x0a, 0x0d, 0x0a, 0x54, 0x72, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x44, 0x72, 0x65, 0x61,
+ 0x6d, 0x77, 0x65, 0x62, 0x20, 0x43, 0x44, 0x20, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20,
+ 0x73, 0x74, 0x65, 0x72, 0x65, 0x6f, 0x2e, 0x2e, 0x2e, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
+ 0x24, 0x81, 0x00, 0xb8, 0x00, 0x52, 0x00, 0x80, 0x00, 0xc0, 0xc8, 0x50, 0x00, 0x93, 0x00, 0x3e,
+ 0x00, 0x6f, 0x00, 0x80, 0xc8, 0xb7, 0x00, 0xfa, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0xc4, 0xc8, 0x00,
+ 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x53, 0x50, 0x45, 0x45, 0x43,
+ 0x48, 0x52, 0x32, 0x34, 0x43, 0x30, 0x30, 0x30, 0x35, 0x2e, 0x52, 0x41, 0x57, 0x00, 0x87, 0x83,
+ 0x81, 0x82, 0x2c, 0x00, 0x46, 0x00, 0x20, 0x00, 0x2e, 0x00, 0x70, 0xc4, 0x00, 0x00, 0x32, 0x00,
+ 0x00, 0x00, 0xb4, 0x00, 0x7c, 0xc3, 0xe2, 0x00, 0xf4, 0x00, 0x0a, 0x00, 0x1a, 0x00, 0x28, 0xc8,
+ 0xe2, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x28, 0x00, 0x2c, 0xc8, 0xf0, 0x00, 0x04, 0x01, 0x64, 0x00,
+ 0x7c, 0x00, 0xcc, 0xc9, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xd4, 0xc9, 0xff, 0xff,
+ 0x2c, 0x00, 0x46, 0x00, 0x20, 0x00, 0x2e, 0x00, 0x70, 0xc4, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
+ 0xb4, 0x00, 0x7c, 0xc3, 0x12, 0x01, 0x24, 0x01, 0x0a, 0x00, 0x1a, 0x00, 0x28, 0xc8, 0x12, 0x01,
+ 0x24, 0x01, 0x1a, 0x00, 0x28, 0x00, 0x2c, 0xc8, 0xf0, 0x00, 0x04, 0x01, 0x64, 0x00, 0x7c, 0x00,
+ 0xcc, 0xc9, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xd4, 0xc9, 0xff, 0xff, 0x00, 0x21,
+ 0x0a, 0x0f, 0xff, 0x00, 0x16, 0x0a, 0x0f, 0xff, 0x00, 0x16, 0x00, 0x0f, 0xff, 0x00, 0x0b, 0x00,
+ 0x0f, 0xff, 0x00, 0x0b, 0x0a, 0x0f, 0xff, 0x00, 0x00, 0x0a, 0x0f, 0xff, 0x01, 0x2c, 0x0a, 0x06,
+ 0xff, 0x01, 0x2c, 0x00, 0x0d, 0xff, 0x02, 0x21, 0x00, 0x06, 0xff, 0x02, 0x16, 0x00, 0x05, 0xff,
+ 0x02, 0x16, 0x0a, 0x10, 0xff, 0x02, 0x0b, 0x0a, 0x10, 0xff, 0x03, 0x2c, 0x00, 0x0f, 0xff, 0x03,
+ 0x21, 0x0a, 0x06, 0xff, 0x03, 0x21, 0x00, 0x05, 0xff, 0x04, 0x0b, 0x1e, 0x06, 0xff, 0x04, 0x16,
+ 0x1e, 0x05, 0xff, 0x04, 0x16, 0x14, 0x0d, 0xff, 0x0a, 0x21, 0x1e, 0x06, 0xff, 0x0a, 0x16, 0x1e,
+ 0x06, 0xff, 0x09, 0x16, 0x0a, 0x06, 0xff, 0x09, 0x16, 0x14, 0x10, 0xff, 0x09, 0x16, 0x1e, 0x10,
+ 0xff, 0x09, 0x16, 0x28, 0x10, 0xff, 0x09, 0x16, 0x32, 0x10, 0xff, 0x06, 0x0b, 0x1e, 0x06, 0xff,
+ 0x06, 0x00, 0x0a, 0x0f, 0xff, 0x06, 0x00, 0x14, 0x0f, 0xff, 0x06, 0x0b, 0x14, 0x0f, 0xff, 0x06,
+ 0x16, 0x14, 0x0f, 0xff, 0x07, 0x0b, 0x14, 0x06, 0xff, 0x07, 0x00, 0x14, 0x06, 0xff, 0x07, 0x00,
+ 0x1e, 0x06, 0xff, 0x37, 0x2c, 0x00, 0x05, 0xff, 0x37, 0x2c, 0x0a, 0x05, 0xff, 0x05, 0x16, 0x1e,
+ 0x06, 0xff, 0x05, 0x16, 0x14, 0x0f, 0xff, 0x05, 0x16, 0x0a, 0x0f, 0xff, 0x18, 0x16, 0x00, 0x0f,
+ 0xff, 0x18, 0x21, 0x00, 0x0f, 0xff, 0x18, 0x2c, 0x00, 0x0f, 0xff, 0x18, 0x21, 0x0a, 0x0f, 0xff,
+ 0x08, 0x00, 0x0a, 0x06, 0xff, 0x08, 0x0b, 0x0a, 0x06, 0xff, 0x08, 0x16, 0x0a, 0x06, 0xff, 0x08,
+ 0x21, 0x0a, 0x06, 0xff, 0x08, 0x21, 0x14, 0x06, 0xff, 0x08, 0x21, 0x1e, 0x06, 0xff, 0x08, 0x21,
+ 0x28, 0x06, 0xff, 0x08, 0x16, 0x28, 0x06, 0xff, 0x08, 0x0b, 0x28, 0x06, 0xff, 0x0b, 0x0b, 0x14,
+ 0x0c, 0xff, 0x0b, 0x0b, 0x1e, 0x0c, 0xff, 0x0b, 0x16, 0x14, 0x0c, 0xff, 0x0b, 0x16, 0x1e, 0x0c,
+ 0xff, 0x0c, 0x16, 0x14, 0x0c, 0xff, 0x0d, 0x16, 0x14, 0x0c, 0xff, 0x0d, 0x21, 0x14, 0x0c, 0xff,
+ 0x0e, 0x2c, 0x14, 0x0c, 0xff, 0x0e, 0x21, 0x00, 0x0c, 0xff, 0x0e, 0x21, 0x0a, 0x0c, 0xff, 0x0e,
+ 0x21, 0x14, 0x0c, 0xff, 0x0e, 0x21, 0x1e, 0x0c, 0xff, 0x0e, 0x21, 0x28, 0x0c, 0xff, 0x0e, 0x16,
+ 0x00, 0x10, 0xff, 0x13, 0x00, 0x00, 0x0c, 0xff, 0x14, 0x00, 0x14, 0x10, 0xff, 0x14, 0x00, 0x1e,
+ 0x10, 0xff, 0x14, 0x0b, 0x1e, 0x10, 0xff, 0x14, 0x00, 0x28, 0x10, 0xff, 0x14, 0x0b, 0x28, 0x10,
+ 0xff, 0x15, 0x0b, 0x0a, 0x0f, 0xff, 0x15, 0x0b, 0x14, 0x0f, 0xff, 0x15, 0x00, 0x14, 0x0f, 0xff,
+ 0x15, 0x16, 0x14, 0x0f, 0xff, 0x15, 0x21, 0x14, 0x0f, 0xff, 0x15, 0x2c, 0x14, 0x0f, 0xff, 0x15,
+ 0x2c, 0x0a, 0x0f, 0xff, 0x16, 0x16, 0x0a, 0x10, 0xff, 0x16, 0x16, 0x14, 0x10, 0xff, 0x17, 0x16,
+ 0x1e, 0x0d, 0xff, 0x17, 0x16, 0x28, 0x0d, 0xff, 0x17, 0x21, 0x28, 0x0d, 0xff, 0x17, 0x0b, 0x28,
+ 0x0d, 0xff, 0x17, 0x00, 0x28, 0x0d, 0xff, 0x17, 0x00, 0x32, 0x0d, 0xff, 0x19, 0x0b, 0x28, 0x10,
+ 0xff, 0x19, 0x0b, 0x32, 0x10, 0xff, 0x19, 0x00, 0x32, 0x10, 0xff, 0x1b, 0x0b, 0x14, 0x10, 0xff,
+ 0x1b, 0x0b, 0x1e, 0x10, 0xff, 0x1d, 0x0b, 0x0a, 0x10, 0xff, 0x2d, 0x16, 0x1e, 0x0c, 0xff, 0x2d,
+ 0x16, 0x28, 0x0c, 0xff, 0x2d, 0x16, 0x32, 0x0c, 0xff, 0x2e, 0x16, 0x28, 0x0c, 0xff, 0x2e, 0x0b,
+ 0x32, 0x0c, 0xff, 0x2e, 0x16, 0x32, 0x0c, 0xff, 0x2e, 0x21, 0x32, 0x0c, 0xff, 0x2f, 0x00, 0x00,
+ 0x0c, 0xff, 0x1a, 0x16, 0x14, 0x10, 0xff, 0x1a, 0x21, 0x0a, 0x10, 0xff, 0x1a, 0x21, 0x14, 0x10,
+ 0xff, 0x1a, 0x21, 0x1e, 0x10, 0xff, 0x1a, 0x2c, 0x1e, 0x10, 0xff, 0x1a, 0x16, 0x1e, 0x10, 0xff,
+ 0x1a, 0x0b, 0x1e, 0x10, 0xff, 0x1a, 0x0b, 0x14, 0x10, 0xff, 0x1a, 0x00, 0x14, 0x10, 0xff, 0x1a,
+ 0x0b, 0x28, 0x10, 0xff, 0x1a, 0x00, 0x28, 0x10, 0xff, 0x1a, 0x16, 0x28, 0x10, 0xff, 0x1a, 0x0b,
+ 0x32, 0x10, 0xff, 0x1c, 0x00, 0x1e, 0x0f, 0xff, 0x1c, 0x00, 0x14, 0x0f, 0xff, 0x1c, 0x00, 0x28,
+ 0x0f, 0xff, 0x1c, 0x0b, 0x1e, 0x0f, 0xff, 0x1c, 0x0b, 0x14, 0x0f, 0xff, 0x1c, 0x16, 0x1e, 0x0f,
+ 0xff, 0x1c, 0x16, 0x14, 0x0f, 0xff, 0xff, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x20, 0x4e, 0x41,
+ 0x4d, 0x45, 0x20, 0x4f, 0x4e, 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
+ 0x10, 0x12, 0x12, 0x11, 0x10, 0x10, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x30, 0x2d, 0x00, 0x08, 0x00, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49,
+ 0x4f, 0x50, 0x00, 0x00, 0x0d, 0x00, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x5a, 0x58, 0x43, 0x56, 0x42, 0x4e, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x3a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x20, 0x44, 0x41, 0x54, 0x41, 0x20, 0x46, 0x49, 0x4c, 0x45, 0x20, 0x43, 0x4f,
+ 0x50, 0x59, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x31, 0x39, 0x39, 0x32, 0x20, 0x43, 0x52, 0x45,
+ 0x41, 0x54, 0x49, 0x56, 0x45, 0x20, 0x52, 0x45, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x30, 0x00, 0x05, 0xff, 0x21, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x06, 0x02, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x31, 0x00, 0x01, 0xff, 0x2c, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x07, 0x02, 0xff, 0xff, 0xff, 0xff, 0x06, 0xff, 0xff, 0xff, 0x01, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x32, 0x00, 0x02, 0xff, 0x21, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x00, 0xff, 0xff, 0x01, 0xff, 0x03, 0xff, 0xff, 0xff, 0x02, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x33, 0x00, 0x05, 0xff, 0x21, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x02, 0x02, 0x00, 0x02, 0x04, 0xff, 0x00, 0xff, 0xff, 0xff, 0x03, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x34, 0x00, 0x17, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0x00, 0x05, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x04, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x35, 0x00, 0x05, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x02, 0x00, 0x04, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x05, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x36, 0x00, 0x05, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0xff, 0xff, 0xff, 0x06, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x37, 0x00, 0xff, 0xff, 0x00, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x07, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x38, 0x00, 0x08, 0xff, 0x00, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0b, 0x28, 0x00, 0x08, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x39, 0x00, 0x09, 0xff, 0x16, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x04, 0x06, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x09, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x30, 0x00, 0x0a, 0xff, 0x21, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x02, 0x00, 0xff, 0xff, 0x02, 0x02, 0x04, 0x16, 0x1e, 0xff, 0x0a, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x31, 0x00, 0x0b, 0xff, 0x0b, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x32, 0x00, 0x0c, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x33, 0x00, 0x0c, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0d, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x34, 0x00, 0x0e, 0xff, 0x2c, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x39, 0x00, 0x13, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x30, 0x00, 0x16, 0xff, 0x00, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0x02, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x31, 0x00, 0x05, 0xff, 0x0b, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0x02, 0x0f, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x32, 0x00, 0x16, 0xff, 0x16, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x33, 0x00, 0x17, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0x02, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x17, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x34, 0x00, 0x05, 0xff, 0x2c, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x06, 0x02, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x18, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x35, 0x00, 0x16, 0xff, 0x0b, 0x28, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x36, 0x00, 0x09, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x04, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x37, 0x00, 0x16, 0xff, 0x0b, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x38, 0x00, 0x05, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x39, 0x00, 0x16, 0xff, 0x0b, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x35, 0x00, 0x05, 0xff, 0x16, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0x01, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x34, 0x00, 0x17, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0x02, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x30, 0x00, 0x0a, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x03, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x32, 0x00, 0x0c, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x33, 0x00, 0x05, 0xff, 0x2c, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x06, 0x02, 0xff, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x34, 0x00, 0x05, 0xff, 0x16, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x03, 0x06, 0x00, 0xff, 0xff, 0xff, 0xff, 0x21, 0x00, 0x03, 0x18, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x32, 0x00, 0x16, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x32, 0x00, 0x16, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x31, 0x00, 0x0b, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x38, 0x00, 0x05, 0xff, 0x0b, 0x14, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x06, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x31, 0x00, 0x05, 0xff, 0x0b, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x01, 0x04, 0x02, 0x0f, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x36, 0x00, 0x09, 0xff, 0x00, 0x28, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x39, 0x00, 0x13, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x38, 0x00, 0x08, 0xff, 0x0b, 0x28, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x31, 0x00, 0x01, 0xff, 0x2c, 0x0a, 0xff, 0xff, 0xff, 0x00,
+ 0x03, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x35, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2d, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x36, 0x00, 0x23, 0xff, 0x16, 0x28, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2e, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x37, 0x00, 0x23, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x35, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2d, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x36, 0x00, 0x23, 0xff, 0x16, 0x32, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2e, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x30, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x32, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x31, 0x00, 0x23, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x32, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x34, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x33, 0x00, 0x23, 0xff, 0x21, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x35, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x34, 0x00, 0x23, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x36, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x35, 0x00, 0x0e, 0xff, 0x2c, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x02, 0x04,
+ 0x01, 0x0a, 0x09, 0x08, 0x06, 0x0b, 0x04, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
+ 0x45, 0x42, 0x2e, 0x44, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
+ 0x44, 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x32,
+ 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x33, 0x00, 0x44, 0x52,
+ 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
+ 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
+ 0x2e, 0x44, 0x30, 0x36, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x45,
+ 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, };
+ ds.assign(src, src + sizeof(src));
+dreamweb();
+}
+
+void DreamGenContext::__dispatch_call(uint16 addr) {
+ switch(addr) {
+ case 0xc000: alleybarksound(); break;
+ case 0xc004: intromusic(); break;
+ case 0xc008: foghornsound(); break;
+ case 0xc00c: receptionist(); break;
+ case 0xc010: smokebloke(); break;
+ case 0xc014: attendant(); break;
+ case 0xc018: manasleep(); break;
+ case 0xc01c: eden(); break;
+ case 0xc020: edeninbath(); break;
+ case 0xc024: malefan(); break;
+ case 0xc028: femalefan(); break;
+ case 0xc02c: louis(); break;
+ case 0xc030: louischair(); break;
+ case 0xc034: manasleep2(); break;
+ case 0xc038: mansatstill(); break;
+ case 0xc03c: tattooman(); break;
+ case 0xc040: drinker(); break;
+ case 0xc044: bartender(); break;
+ case 0xc048: othersmoker(); break;
+ case 0xc04c: barwoman(); break;
+ case 0xc050: interviewer(); break;
+ case 0xc054: soldier1(); break;
+ case 0xc058: rockstar(); break;
+ case 0xc05c: helicopter(); break;
+ case 0xc060: mugger(); break;
+ case 0xc064: aide(); break;
+ case 0xc068: businessman(); break;
+ case 0xc06c: poolguard(); break;
+ case 0xc070: security(); break;
+ case 0xc074: heavy(); break;
+ case 0xc078: bossman(); break;
+ case 0xc07c: gamer(); break;
+ case 0xc080: sparkydrip(); break;
+ case 0xc084: carparkdrip(); break;
+ case 0xc088: keeper(); break;
+ case 0xc08c: candles1(); break;
+ case 0xc090: smallcandle(); break;
+ case 0xc094: intromagic1(); break;
+ case 0xc098: candles(); break;
+ case 0xc09c: candles2(); break;
+ case 0xc0a0: gates(); break;
+ case 0xc0a4: intromagic2(); break;
+ case 0xc0a8: intromagic3(); break;
+ case 0xc0ac: intromonks1(); break;
+ case 0xc0b0: intromonks2(); break;
+ case 0xc0b4: handclap(); break;
+ case 0xc0b8: monks2text(); break;
+ case 0xc0bc: intro1text(); break;
+ case 0xc0c0: intro2text(); break;
+ case 0xc0c4: intro3text(); break;
+ case 0xc0c8: monkandryan(); break;
+ case 0xc0cc: endgameseq(); break;
+ case 0xc0d0: rollendcredits(); break;
+ case 0xc0d4: priest(); break;
+ case 0xc0d8: madmanstelly(); break;
+ case 0xc0dc: madman(); break;
+ case 0xc0e0: madmantext(); break;
+ case 0xc0e4: madmode(); break;
+ case 0xc0e8: priesttext(); break;
+ case 0xc0ec: textforend(); break;
+ case 0xc0f0: textformonk(); break;
+ case 0xc0f4: drunk(); break;
+ case 0xc0f8: advisor(); break;
+ case 0xc0fc: copper(); break;
+ case 0xc100: sparky(); break;
+ case 0xc104: train(); break;
+ case 0xc108: addtopeoplelist(); break;
+ case 0xc10c: showgamereel(); break;
+ case 0xc110: checkspeed(); break;
+ case 0xc114: clearsprites(); break;
+ case 0xc118: makesprite(); break;
+ case 0xc11c: delsprite(); break;
+ case 0xc120: spriteupdate(); break;
+ case 0xc124: printsprites(); break;
+ case 0xc128: printasprite(); break;
+ case 0xc12c: checkone(); break;
+ case 0xc130: findsource(); break;
+ case 0xc134: initman(); break;
+ case 0xc138: mainman(); break;
+ case 0xc13c: aboutturn(); break;
+ case 0xc140: walking(); break;
+ case 0xc144: facerightway(); break;
+ case 0xc148: checkforexit(); break;
+ case 0xc14c: adjustdown(); break;
+ case 0xc150: adjustup(); break;
+ case 0xc154: adjustleft(); break;
+ case 0xc158: adjustright(); break;
+ case 0xc15c: reminders(); break;
+ case 0xc160: initrain(); break;
+ case 0xc164: splitintolines(); break;
+ case 0xc168: getblockofpixel(); break;
+ case 0xc16c: showrain(); break;
+ case 0xc170: backobject(); break;
+ case 0xc174: liftsprite(); break;
+ case 0xc178: liftnoise(); break;
+ case 0xc17c: random(); break;
+ case 0xc180: steady(); break;
+ case 0xc184: constant(); break;
+ case 0xc188: doorway(); break;
+ case 0xc18c: widedoor(); break;
+ case 0xc190: dodoor(); break;
+ case 0xc194: lockeddoorway(); break;
+ case 0xc198: updatepeople(); break;
+ case 0xc19c: getreelframeax(); break;
+ case 0xc1a0: reelsonscreen(); break;
+ case 0xc1a4: plotreel(); break;
+ case 0xc1a8: soundonreels(); break;
+ case 0xc1ac: reconstruct(); break;
+ case 0xc1b0: dealwithspecial(); break;
+ case 0xc1b4: movemap(); break;
+ case 0xc1b8: getreelstart(); break;
+ case 0xc1bc: showreelframe(); break;
+ case 0xc1c0: deleverything(); break;
+ case 0xc1c4: dumpeverything(); break;
+ case 0xc1c8: allocatework(); break;
+ case 0xc1cc: showpcx(); break;
+ case 0xc1d8: loadpalfromiff(); break;
+ case 0xc1dc: setmode(); break;
+ case 0xc1ec: paneltomap(); break;
+ case 0xc1f0: maptopanel(); break;
+ case 0xc1f4: dumpmap(); break;
+ case 0xc1f8: pixelcheckset(); break;
+ case 0xc1fc: createpanel(); break;
+ case 0xc200: createpanel2(); break;
+ case 0xc204: clearwork(); break;
+ case 0xc208: vsync(); break;
+ case 0xc20c: doshake(); break;
+ case 0xc210: zoom(); break;
+ case 0xc214: delthisone(); break;
+ case 0xc228: doblocks(); break;
+ case 0xc22c: showframe(); break;
+ case 0xc238: frameoutbh(); break;
+ case 0xc23c: frameoutfx(); break;
+ case 0xc240: transferinv(); break;
+ case 0xc244: transfermap(); break;
+ case 0xc248: fadedos(); break;
+ case 0xc24c: dofade(); break;
+ case 0xc250: clearendpal(); break;
+ case 0xc254: clearpalette(); break;
+ case 0xc258: fadescreenup(); break;
+ case 0xc25c: fadetowhite(); break;
+ case 0xc260: fadefromwhite(); break;
+ case 0xc264: fadescreenups(); break;
+ case 0xc268: fadescreendownhalf(); break;
+ case 0xc26c: fadescreenuphalf(); break;
+ case 0xc270: fadescreendown(); break;
+ case 0xc274: fadescreendowns(); break;
+ case 0xc278: clearstartpal(); break;
+ case 0xc27c: showgun(); break;
+ case 0xc280: rollendcredits2(); break;
+ case 0xc284: rollem(); break;
+ case 0xc288: fadecalculation(); break;
+ case 0xc28c: greyscalesum(); break;
+ case 0xc290: showgroup(); break;
+ case 0xc294: paltostartpal(); break;
+ case 0xc298: endpaltostart(); break;
+ case 0xc29c: startpaltoend(); break;
+ case 0xc2a0: paltoendpal(); break;
+ case 0xc2a4: allpalette(); break;
+ case 0xc2a8: dumpcurrent(); break;
+ case 0xc2ac: fadedownmon(); break;
+ case 0xc2b0: fadeupmon(); break;
+ case 0xc2b4: fadeupmonfirst(); break;
+ case 0xc2b8: fadeupyellows(); break;
+ case 0xc2bc: initialmoncols(); break;
+ case 0xc2c0: titles(); break;
+ case 0xc2c4: endgame(); break;
+ case 0xc2c8: monkspeaking(); break;
+ case 0xc2cc: showmonk(); break;
+ case 0xc2d0: gettingshot(); break;
+ case 0xc2d4: credits(); break;
+ case 0xc2d8: biblequote(); break;
+ case 0xc2dc: hangone(); break;
+ case 0xc2e0: intro(); break;
+ case 0xc2e4: runintroseq(); break;
+ case 0xc2e8: runendseq(); break;
+ case 0xc2ec: loadintroroom(); break;
+ case 0xc2f0: mode640x480(); break;
+ case 0xc2f4: set16colpalette(); break;
+ case 0xc2f8: realcredits(); break;
+ case 0xc2fc: printchar(); break;
+ case 0xc300: kernchars(); break;
+ case 0xc304: printslow(); break;
+ case 0xc308: waitframes(); break;
+ case 0xc30c: printboth(); break;
+ case 0xc310: printdirect(); break;
+ case 0xc314: monprint(); break;
+ case 0xc318: getnumber(); break;
+ case 0xc31c: getnextword(); break;
+ case 0xc320: fillryan(); break;
+ case 0xc324: fillopen(); break;
+ case 0xc328: findallryan(); break;
+ case 0xc32c: findallopen(); break;
+ case 0xc330: obtoinv(); break;
+ case 0xc334: isitworn(); break;
+ case 0xc338: makeworn(); break;
+ case 0xc33c: examineob(); break;
+ case 0xc340: makemainscreen(); break;
+ case 0xc344: getbackfromob(); break;
+ case 0xc348: incryanpage(); break;
+ case 0xc34c: openinv(); break;
+ case 0xc350: showryanpage(); break;
+ case 0xc354: openob(); break;
+ case 0xc358: obicons(); break;
+ case 0xc35c: examicon(); break;
+ case 0xc360: obpicture(); break;
+ case 0xc364: describeob(); break;
+ case 0xc368: additionaltext(); break;
+ case 0xc36c: obsthatdothings(); break;
+ case 0xc370: getobtextstart(); break;
+ case 0xc374: searchforsame(); break;
+ case 0xc378: findnextcolon(); break;
+ case 0xc37c: inventory(); break;
+ case 0xc380: setpickup(); break;
+ case 0xc384: examinventory(); break;
+ case 0xc388: reexfrominv(); break;
+ case 0xc38c: reexfromopen(); break;
+ case 0xc390: swapwithinv(); break;
+ case 0xc394: swapwithopen(); break;
+ case 0xc398: intoinv(); break;
+ case 0xc39c: deletetaken(); break;
+ case 0xc3a0: outofinv(); break;
+ case 0xc3a4: getfreead(); break;
+ case 0xc3a8: getexad(); break;
+ case 0xc3ac: geteitherad(); break;
+ case 0xc3b0: getanyad(); break;
+ case 0xc3b4: getanyaddir(); break;
+ case 0xc3b8: getopenedsize(); break;
+ case 0xc3bc: getsetad(); break;
+ case 0xc3c0: findinvpos(); break;
+ case 0xc3c4: findopenpos(); break;
+ case 0xc3c8: dropobject(); break;
+ case 0xc3cc: droperror(); break;
+ case 0xc3d0: cantdrop(); break;
+ case 0xc3d4: wornerror(); break;
+ case 0xc3d8: removeobfrominv(); break;
+ case 0xc3dc: selectopenob(); break;
+ case 0xc3e0: useopened(); break;
+ case 0xc3e4: errormessage1(); break;
+ case 0xc3e8: errormessage2(); break;
+ case 0xc3ec: errormessage3(); break;
+ case 0xc3f0: checkobjectsize(); break;
+ case 0xc3f4: outofopen(); break;
+ case 0xc3f8: transfertoex(); break;
+ case 0xc3fc: pickupconts(); break;
+ case 0xc400: transfercontoex(); break;
+ case 0xc404: transfertext(); break;
+ case 0xc408: getexpos(); break;
+ case 0xc40c: purgealocation(); break;
+ case 0xc410: emergencypurge(); break;
+ case 0xc414: purgeanitem(); break;
+ case 0xc418: deleteexobject(); break;
+ case 0xc41c: deleteexframe(); break;
+ case 0xc420: deleteextext(); break;
+ case 0xc424: blockget(); break;
+ case 0xc428: drawfloor(); break;
+ case 0xc42c: calcmapad(); break;
+ case 0xc430: getdimension(); break;
+ case 0xc434: addalong(); break;
+ case 0xc438: addlength(); break;
+ case 0xc43c: drawflags(); break;
+ case 0xc440: eraseoldobs(); break;
+ case 0xc444: showallobs(); break;
+ case 0xc448: makebackob(); break;
+ case 0xc44c: showallfree(); break;
+ case 0xc450: showallex(); break;
+ case 0xc454: calcfrframe(); break;
+ case 0xc458: finalframe(); break;
+ case 0xc45c: adjustlen(); break;
+ case 0xc460: getmapad(); break;
+ case 0xc464: getxad(); break;
+ case 0xc468: getyad(); break;
+ case 0xc46c: autolook(); break;
+ case 0xc470: look(); break;
+ case 0xc474: dolook(); break;
+ case 0xc478: redrawmainscrn(); break;
+ case 0xc47c: getback1(); break;
+ case 0xc480: talk(); break;
+ case 0xc484: convicons(); break;
+ case 0xc488: getpersframe(); break;
+ case 0xc48c: starttalk(); break;
+ case 0xc490: getpersontext(); break;
+ case 0xc494: moretalk(); break;
+ case 0xc498: dosometalk(); break;
+ case 0xc49c: hangonpq(); break;
+ case 0xc4a0: redes(); break;
+ case 0xc4a4: newplace(); break;
+ case 0xc4a8: selectlocation(); break;
+ case 0xc4ac: showcity(); break;
+ case 0xc4b0: lookatplace(); break;
+ case 0xc4b4: getundercentre(); break;
+ case 0xc4b8: putundercentre(); break;
+ case 0xc4bc: locationpic(); break;
+ case 0xc4c0: getdestinfo(); break;
+ case 0xc4c4: showarrows(); break;
+ case 0xc4c8: nextdest(); break;
+ case 0xc4cc: lastdest(); break;
+ case 0xc4d0: destselect(); break;
+ case 0xc4d4: getlocation(); break;
+ case 0xc4d8: setlocation(); break;
+ case 0xc4dc: resetlocation(); break;
+ case 0xc4e0: readdesticon(); break;
+ case 0xc4e4: readcitypic(); break;
+ case 0xc4e8: usemon(); break;
+ case 0xc4ec: printoutermon(); break;
+ case 0xc4f0: loadpersonal(); break;
+ case 0xc4f4: loadnews(); break;
+ case 0xc4f8: loadcart(); break;
+ case 0xc4fc: lookininterface(); break;
+ case 0xc500: turnonpower(); break;
+ case 0xc504: randomaccess(); break;
+ case 0xc508: powerlighton(); break;
+ case 0xc50c: powerlightoff(); break;
+ case 0xc510: accesslighton(); break;
+ case 0xc514: accesslightoff(); break;
+ case 0xc518: locklighton(); break;
+ case 0xc51c: locklightoff(); break;
+ case 0xc520: input(); break;
+ case 0xc524: makecaps(); break;
+ case 0xc528: delchar(); break;
+ case 0xc52c: execcommand(); break;
+ case 0xc530: neterror(); break;
+ case 0xc534: dircom(); break;
+ case 0xc538: searchforfiles(); break;
+ case 0xc53c: signon(); break;
+ case 0xc540: showkeys(); break;
+ case 0xc544: read(); break;
+ case 0xc548: dirfile(); break;
+ case 0xc54c: getkeyandlogo(); break;
+ case 0xc550: searchforstring(); break;
+ case 0xc554: parser(); break;
+ case 0xc558: scrollmonitor(); break;
+ case 0xc55c: lockmon(); break;
+ case 0xc560: monitorlogo(); break;
+ case 0xc564: printlogo(); break;
+ case 0xc568: showcurrentfile(); break;
+ case 0xc56c: monmessage(); break;
+ case 0xc570: processtrigger(); break;
+ case 0xc574: triggermessage(); break;
+ case 0xc578: printcurs(); break;
+ case 0xc57c: delcurs(); break;
+ case 0xc580: useobject(); break;
+ case 0xc584: useroutine(); break;
+ case 0xc588: wheelsound(); break;
+ case 0xc58c: runtap(); break;
+ case 0xc590: playguitar(); break;
+ case 0xc594: hotelcontrol(); break;
+ case 0xc598: hotelbell(); break;
+ case 0xc59c: opentomb(); break;
+ case 0xc5a0: usetrainer(); break;
+ case 0xc5a4: nothelderror(); break;
+ case 0xc5a8: usepipe(); break;
+ case 0xc5ac: usefullcart(); break;
+ case 0xc5b0: useplinth(); break;
+ case 0xc5b4: chewy(); break;
+ case 0xc5b8: useladder(); break;
+ case 0xc5bc: useladderb(); break;
+ case 0xc5c0: slabdoora(); break;
+ case 0xc5c4: slabdoorb(); break;
+ case 0xc5c8: slabdoord(); break;
+ case 0xc5cc: slabdoorc(); break;
+ case 0xc5d0: slabdoore(); break;
+ case 0xc5d4: slabdoorf(); break;
+ case 0xc5d8: useslab(); break;
+ case 0xc5dc: usecart(); break;
+ case 0xc5e0: useclearbox(); break;
+ case 0xc5e4: usecoveredbox(); break;
+ case 0xc5e8: userailing(); break;
+ case 0xc5ec: useopenbox(); break;
+ case 0xc5f0: wearwatch(); break;
+ case 0xc5f4: wearshades(); break;
+ case 0xc5f8: sitdowninbar(); break;
+ case 0xc5fc: usechurchhole(); break;
+ case 0xc600: usehole(); break;
+ case 0xc604: usealtar(); break;
+ case 0xc608: opentvdoor(); break;
+ case 0xc60c: usedryer(); break;
+ case 0xc610: openlouis(); break;
+ case 0xc614: nextcolon(); break;
+ case 0xc618: openyourneighbour(); break;
+ case 0xc61c: usewindow(); break;
+ case 0xc620: usebalcony(); break;
+ case 0xc624: openryan(); break;
+ case 0xc628: openpoolboss(); break;
+ case 0xc62c: openeden(); break;
+ case 0xc630: opensarters(); break;
+ case 0xc634: isitright(); break;
+ case 0xc638: drawitall(); break;
+ case 0xc63c: openhoteldoor(); break;
+ case 0xc640: openhoteldoor2(); break;
+ case 0xc644: grafittidoor(); break;
+ case 0xc648: trapdoor(); break;
+ case 0xc64c: callhotellift(); break;
+ case 0xc650: calledenslift(); break;
+ case 0xc654: calledensdlift(); break;
+ case 0xc658: usepoolreader(); break;
+ case 0xc65c: uselighter(); break;
+ case 0xc660: showseconduse(); break;
+ case 0xc664: usecardreader1(); break;
+ case 0xc668: usecardreader2(); break;
+ case 0xc66c: usecardreader3(); break;
+ case 0xc670: usecashcard(); break;
+ case 0xc674: lookatcard(); break;
+ case 0xc678: moneypoke(); break;
+ case 0xc67c: usecontrol(); break;
+ case 0xc680: usehatch(); break;
+ case 0xc684: usewire(); break;
+ case 0xc688: usehandle(); break;
+ case 0xc68c: useelevator1(); break;
+ case 0xc690: showfirstuse(); break;
+ case 0xc694: useelevator3(); break;
+ case 0xc698: useelevator4(); break;
+ case 0xc69c: useelevator2(); break;
+ case 0xc6a0: useelevator5(); break;
+ case 0xc6a4: usekey(); break;
+ case 0xc6a8: usestereo(); break;
+ case 0xc6ac: usecooker(); break;
+ case 0xc6b0: useaxe(); break;
+ case 0xc6b4: useelvdoor(); break;
+ case 0xc6b8: withwhat(); break;
+ case 0xc6bc: selectob(); break;
+ case 0xc6c0: compare(); break;
+ case 0xc6c4: findsetobject(); break;
+ case 0xc6c8: findexobject(); break;
+ case 0xc6cc: isryanholding(); break;
+ case 0xc6d0: checkinside(); break;
+ case 0xc6d4: usetext(); break;
+ case 0xc6d8: putbackobstuff(); break;
+ case 0xc6dc: showpuztext(); break;
+ case 0xc6e0: findpuztext(); break;
+ case 0xc6e4: placesetobject(); break;
+ case 0xc6e8: removesetobject(); break;
+ case 0xc6ec: issetobonmap(); break;
+ case 0xc6f0: placefreeobject(); break;
+ case 0xc6f4: removefreeobject(); break;
+ case 0xc6f8: findormake(); break;
+ case 0xc6fc: switchryanon(); break;
+ case 0xc700: switchryanoff(); break;
+ case 0xc704: setallchanges(); break;
+ case 0xc708: dochange(); break;
+ case 0xc70c: autoappear(); break;
+ case 0xc710: getundertimed(); break;
+ case 0xc714: putundertimed(); break;
+ case 0xc718: dumptimedtext(); break;
+ case 0xc71c: setuptimeduse(); break;
+ case 0xc720: setuptimedtemp(); break;
+ case 0xc724: usetimedtext(); break;
+ case 0xc728: edenscdplayer(); break;
+ case 0xc72c: usewall(); break;
+ case 0xc730: usechurchgate(); break;
+ case 0xc734: usegun(); break;
+ case 0xc738: useshield(); break;
+ case 0xc73c: usebuttona(); break;
+ case 0xc740: useplate(); break;
+ case 0xc744: usewinch(); break;
+ case 0xc748: entercode(); break;
+ case 0xc74c: loadkeypad(); break;
+ case 0xc750: quitkey(); break;
+ case 0xc754: addtopresslist(); break;
+ case 0xc758: buttonone(); break;
+ case 0xc75c: buttontwo(); break;
+ case 0xc760: buttonthree(); break;
+ case 0xc764: buttonfour(); break;
+ case 0xc768: buttonfive(); break;
+ case 0xc76c: buttonsix(); break;
+ case 0xc770: buttonseven(); break;
+ case 0xc774: buttoneight(); break;
+ case 0xc778: buttonnine(); break;
+ case 0xc77c: buttonnought(); break;
+ case 0xc780: buttonenter(); break;
+ case 0xc784: buttonpress(); break;
+ case 0xc788: showouterpad(); break;
+ case 0xc78c: showkeypad(); break;
+ case 0xc790: singlekey(); break;
+ case 0xc794: dumpkeypad(); break;
+ case 0xc798: usemenu(); break;
+ case 0xc79c: dumpmenu(); break;
+ case 0xc7a0: getundermenu(); break;
+ case 0xc7a4: putundermenu(); break;
+ case 0xc7a8: showoutermenu(); break;
+ case 0xc7ac: showmenu(); break;
+ case 0xc7b0: loadmenu(); break;
+ case 0xc7b4: viewfolder(); break;
+ case 0xc7b8: nextfolder(); break;
+ case 0xc7bc: folderhints(); break;
+ case 0xc7c0: lastfolder(); break;
+ case 0xc7c4: loadfolder(); break;
+ case 0xc7c8: showfolder(); break;
+ case 0xc7cc: folderexit(); break;
+ case 0xc7d0: showleftpage(); break;
+ case 0xc7d4: showrightpage(); break;
+ case 0xc7d8: entersymbol(); break;
+ case 0xc7dc: quitsymbol(); break;
+ case 0xc7e0: settopleft(); break;
+ case 0xc7e4: settopright(); break;
+ case 0xc7e8: setbotleft(); break;
+ case 0xc7ec: setbotright(); break;
+ case 0xc7f0: dumpsymbol(); break;
+ case 0xc7f4: showsymbol(); break;
+ case 0xc7f8: nextsymbol(); break;
+ case 0xc7fc: updatesymboltop(); break;
+ case 0xc800: updatesymbolbot(); break;
+ case 0xc804: dumpsymbox(); break;
+ case 0xc808: usediary(); break;
+ case 0xc80c: showdiary(); break;
+ case 0xc810: showdiarykeys(); break;
+ case 0xc814: dumpdiarykeys(); break;
+ case 0xc818: diarykeyp(); break;
+ case 0xc81c: diarykeyn(); break;
+ case 0xc820: showdiarypage(); break;
+ case 0xc824: findtext1(); break;
+ case 0xc828: zoomonoff(); break;
+ case 0xc82c: saveload(); break;
+ case 0xc830: dosaveload(); break;
+ case 0xc834: getbackfromops(); break;
+ case 0xc838: showmainops(); break;
+ case 0xc83c: showdiscops(); break;
+ case 0xc840: loadsavebox(); break;
+ case 0xc844: loadgame(); break;
+ case 0xc848: getbacktoops(); break;
+ case 0xc84c: discops(); break;
+ case 0xc850: savegame(); break;
+ case 0xc854: actualsave(); break;
+ case 0xc858: actualload(); break;
+ case 0xc85c: selectslot2(); break;
+ case 0xc860: checkinput(); break;
+ case 0xc864: getnamepos(); break;
+ case 0xc868: showopbox(); break;
+ case 0xc86c: showloadops(); break;
+ case 0xc870: showsaveops(); break;
+ case 0xc874: selectslot(); break;
+ case 0xc878: showslots(); break;
+ case 0xc87c: shownames(); break;
+ case 0xc880: dosreturn(); break;
+ case 0xc884: error(); break;
+ case 0xc888: namestoold(); break;
+ case 0xc88c: oldtonames(); break;
+ case 0xc890: savefilewrite(); break;
+ case 0xc894: savefileread(); break;
+ case 0xc898: saveposition(); break;
+ case 0xc89c: loadposition(); break;
+ case 0xc8a0: loadseg(); break;
+ case 0xc8a4: makeheader(); break;
+ case 0xc8a8: storeit(); break;
+ case 0xc8ac: saveseg(); break;
+ case 0xc8b0: findlen(); break;
+ case 0xc8b4: scanfornames(); break;
+ case 0xc8b8: decide(); break;
+ case 0xc8bc: showdecisions(); break;
+ case 0xc8c0: newgame(); break;
+ case 0xc8c4: loadold(); break;
+ case 0xc8c8: loadspeech(); break;
+ case 0xc8cc: createname(); break;
+ case 0xc8d0: loadsample(); break;
+ case 0xc8d4: loadsecondsample(); break;
+ case 0xc8d8: soundstartup(); break;
+ case 0xc8dc: trysoundalloc(); break;
+ case 0xc8e0: setsoundoff(); break;
+ case 0xc8e4: checksoundint(); break;
+ case 0xc8e8: enablesoundint(); break;
+ case 0xc8ec: disablesoundint(); break;
+ case 0xc8f0: interupttest(); break;
+ case 0xc8f4: soundend(); break;
+ case 0xc8f8: out22c(); break;
+ case 0xc8fc: playchannel0(); break;
+ case 0xc900: playchannel1(); break;
+ case 0xc904: makenextblock(); break;
+ case 0xc908: volumeadjust(); break;
+ case 0xc90c: loopchannel0(); break;
+ case 0xc910: cancelch0(); break;
+ case 0xc914: cancelch1(); break;
+ case 0xc918: channel0only(); break;
+ case 0xc91c: channel1only(); break;
+ case 0xc920: channel0tran(); break;
+ case 0xc924: bothchannels(); break;
+ case 0xc928: saveems(); break;
+ case 0xc92c: restoreems(); break;
+ case 0xc930: domix(); break;
+ case 0xc934: dmaend(); break;
+ case 0xc938: startdmablock(); break;
+ case 0xc93c: setuppit(); break;
+ case 0xc940: getridofpit(); break;
+ case 0xc944: pitinterupt(); break;
+ case 0xc948: dreamweb(); break;
+ case 0xc94c: entrytexts(); break;
+ case 0xc950: entryanims(); break;
+ case 0xc954: initialinv(); break;
+ case 0xc958: pickupob(); break;
+ case 0xc95c: setupemm(); break;
+ case 0xc960: removeemm(); break;
+ case 0xc964: checkforemm(); break;
+ case 0xc968: checkbasemem(); break;
+ case 0xc96c: allocatebuffers(); break;
+ case 0xc970: clearbuffers(); break;
+ case 0xc974: clearchanges(); break;
+ case 0xc978: clearbeforeload(); break;
+ case 0xc97c: clearreels(); break;
+ case 0xc980: clearrest(); break;
+ case 0xc984: deallocatemem(); break;
+ case 0xc988: allocatemem(); break;
+ case 0xc990: parseblaster(); break;
+ case 0xc994: startup(); break;
+ case 0xc998: startup1(); break;
+ case 0xc99c: screenupdate(); break;
+ case 0xc9a0: watchreel(); break;
+ case 0xc9a4: checkforshake(); break;
+ case 0xc9a8: watchcount(); break;
+ case 0xc9ac: showtime(); break;
+ case 0xc9b0: dumpwatch(); break;
+ case 0xc9b4: showbyte(); break;
+ case 0xc9b8: onedigit(); break;
+ case 0xc9bc: twodigitnum(); break;
+ case 0xc9c0: showword(); break;
+ case 0xc9c4: convnum(); break;
+ case 0xc9c8: mainscreen(); break;
+ case 0xc9cc: madmanrun(); break;
+ case 0xc9d0: checkcoords(); break;
+ case 0xc9d4: identifyob(); break;
+ case 0xc9d8: checkifperson(); break;
+ case 0xc9dc: checkifset(); break;
+ case 0xc9e0: checkifex(); break;
+ case 0xc9e4: checkiffree(); break;
+ case 0xc9e8: isitdescribed(); break;
+ case 0xc9ec: findpathofpoint(); break;
+ case 0xc9f0: findfirstpath(); break;
+ case 0xc9f4: turnpathon(); break;
+ case 0xc9f8: turnpathoff(); break;
+ case 0xc9fc: turnanypathon(); break;
+ case 0xca00: turnanypathoff(); break;
+ case 0xca04: checkifpathison(); break;
+ case 0xca08: afternewroom(); break;
+ case 0xca0c: atmospheres(); break;
+ case 0xca10: walkintoroom(); break;
+ case 0xca14: afterintroroom(); break;
+ case 0xca18: obname(); break;
+ case 0xca1c: finishedwalking(); break;
+ case 0xca20: examineobtext(); break;
+ case 0xca24: commandwithob(); break;
+ case 0xca28: commandonly(); break;
+ case 0xca2c: printmessage(); break;
+ case 0xca30: printmessage2(); break;
+ case 0xca34: blocknametext(); break;
+ case 0xca38: personnametext(); break;
+ case 0xca3c: walktotext(); break;
+ case 0xca40: getflagunderp(); break;
+ case 0xca44: setwalk(); break;
+ case 0xca48: autosetwalk(); break;
+ case 0xca4c: checkdest(); break;
+ case 0xca50: bresenhams(); break;
+ case 0xca54: workoutframes(); break;
+ case 0xca58: getroomspaths(); break;
+ case 0xca5c: copyname(); break;
+ case 0xca60: findobname(); break;
+ case 0xca64: showicon(); break;
+ case 0xca68: middlepanel(); break;
+ case 0xca6c: showman(); break;
+ case 0xca70: showpanel(); break;
+ case 0xca74: roomname(); break;
+ case 0xca78: usecharset1(); break;
+ case 0xca7c: usetempcharset(); break;
+ case 0xca80: showexit(); break;
+ case 0xca84: panelicons1(); break;
+ case 0xca88: showwatch(); break;
+ case 0xca8c: gettime(); break;
+ case 0xca90: zoomicon(); break;
+ case 0xca94: showblink(); break;
+ case 0xca98: dumpblink(); break;
+ case 0xca9c: worktoscreenm(); break;
+ case 0xcaa0: blank(); break;
+ case 0xcaa4: allpointer(); break;
+ case 0xcaa8: hangonp(); break;
+ case 0xcaac: hangonw(); break;
+ case 0xcab0: hangoncurs(); break;
+ case 0xcab4: getunderzoom(); break;
+ case 0xcab8: dumpzoom(); break;
+ case 0xcabc: putunderzoom(); break;
+ case 0xcac0: crosshair(); break;
+ case 0xcac4: showpointer(); break;
+ case 0xcac8: delpointer(); break;
+ case 0xcacc: dumppointer(); break;
+ case 0xcad0: undertextline(); break;
+ case 0xcad4: deltextline(); break;
+ case 0xcad8: dumptextline(); break;
+ case 0xcadc: animpointer(); break;
+ case 0xcae0: setmouse(); break;
+ case 0xcae4: readmouse(); break;
+ case 0xcae8: mousecall(); break;
+ case 0xcaec: readmouse1(); break;
+ case 0xcaf0: readmouse2(); break;
+ case 0xcaf4: readmouse3(); break;
+ case 0xcaf8: readmouse4(); break;
+ case 0xcafc: readkey(); break;
+ case 0xcb04: randomnum1(); break;
+ case 0xcb08: randomnum2(); break;
+ case 0xcb10: hangon(); break;
+ case 0xcb14: loadtraveltext(); break;
+ case 0xcb18: loadintotemp(); break;
+ case 0xcb1c: loadintotemp2(); break;
+ case 0xcb20: loadintotemp3(); break;
+ case 0xcb24: loadtempcharset(); break;
+ case 0xcb28: standardload(); break;
+ case 0xcb2c: loadtemptext(); break;
+ case 0xcb30: loadroom(); break;
+ case 0xcb34: loadroomssample(); break;
+ case 0xcb38: getridofreels(); break;
+ case 0xcb3c: getridofall(); break;
+ case 0xcb40: restorereels(); break;
+ case 0xcb44: restoreall(); break;
+ case 0xcb48: sortoutmap(); break;
+ case 0xcb4c: startloading(); break;
+ case 0xcb50: disablepath(); break;
+ case 0xcb54: findxyfrompath(); break;
+ case 0xcb58: findroominloc(); break;
+ case 0xcb5c: getroomdata(); break;
+ case 0xcb60: readheader(); break;
+ case 0xcb64: dontloadseg(); break;
+ case 0xcb68: allocateload(); break;
+ case 0xcb6c: fillspace(); break;
+ case 0xcb70: getridoftemp(); break;
+ case 0xcb74: getridoftemptext(); break;
+ case 0xcb78: getridoftemp2(); break;
+ case 0xcb7c: getridoftemp3(); break;
+ case 0xcb80: getridoftempcharset(); break;
+ case 0xcb84: getridoftempsp(); break;
+ case 0xcb88: readsetdata(); break;
+ case 0xcb8c: createfile(); break;
+ case 0xcb90: openfile(); break;
+ case 0xcb94: openfilefromc(); break;
+ case 0xcb98: makename(); break;
+ case 0xcb9c: openfilenocheck(); break;
+ case 0xcba0: openforsave(); break;
+ case 0xcba4: closefile(); break;
+ case 0xcba8: readfromfile(); break;
+ case 0xcbac: setkeyboardint(); break;
+ case 0xcbb0: resetkeyboard(); break;
+ case 0xcbb4: keyboardread(); break;
+ case 0xcbb8: walkandexamine(); break;
+ case 0xcbbc: doload(); break;
+ case 0xcbc0: generalerror(); break;
+ default: ::error("invalid call to %04x dispatched", (uint16)ax);
+ }
+}
+
+} /*namespace*/
diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h
new file mode 100644
index 0000000000..71c466da24
--- /dev/null
+++ b/engines/dreamweb/dreamgen.h
@@ -0,0 +1,1345 @@
+#ifndef TASMRECOVER_DREAMGEN_STUBS_H__
+#define TASMRECOVER_DREAMGEN_STUBS_H__
+
+/* PLEASE DO NOT MODIFY THIS FILE. ALL CHANGES WILL BE LOST! LOOK FOR README FOR DETAILS */
+
+
+#include "dreamweb/runtime.h"
+
+namespace DreamGen {
+
+class DreamGenContext : public Context {
+public:
+ void __start();
+ void __dispatch_call(uint16 addr);
+
+ const static uint16 kStartvars = 0;
+ const static uint16 kProgresspoints = 1;
+ const static uint16 kWatchon = 2;
+ const static uint16 kShadeson = 3;
+ const static uint16 kSecondcount = 4;
+ const static uint16 kMinutecount = 5;
+ const static uint16 kHourcount = 6;
+ const static uint16 kZoomon = 7;
+ const static uint16 kLocation = 8;
+ const static uint16 kExpos = 9;
+ const static uint16 kExframepos = 10;
+ const static uint16 kExtextpos = 12;
+ const static uint16 kCard1money = 14;
+ const static uint16 kListpos = 16;
+ const static uint16 kRyanpage = 18;
+ const static uint16 kWatchingtime = 19;
+ const static uint16 kReeltowatch = 21;
+ const static uint16 kEndwatchreel = 23;
+ const static uint16 kSpeedcount = 25;
+ const static uint16 kWatchspeed = 26;
+ const static uint16 kReeltohold = 27;
+ const static uint16 kEndofholdreel = 29;
+ const static uint16 kWatchmode = 31;
+ const static uint16 kDestafterhold = 32;
+ const static uint16 kNewsitem = 33;
+ const static uint16 kLiftflag = 34;
+ const static uint16 kLiftpath = 35;
+ const static uint16 kLockstatus = 36;
+ const static uint16 kDoorpath = 37;
+ const static uint16 kCounttoopen = 38;
+ const static uint16 kCounttoclose = 39;
+ const static uint16 kRockstardead = 40;
+ const static uint16 kGeneraldead = 41;
+ const static uint16 kSartaindead = 42;
+ const static uint16 kAidedead = 43;
+ const static uint16 kBeenmugged = 44;
+ const static uint16 kGunpassflag = 45;
+ const static uint16 kCanmovealtar = 46;
+ const static uint16 kTalkedtoattendant = 47;
+ const static uint16 kTalkedtosparky = 48;
+ const static uint16 kTalkedtoboss = 49;
+ const static uint16 kTalkedtorecep = 50;
+ const static uint16 kCardpassflag = 51;
+ const static uint16 kMadmanflag = 52;
+ const static uint16 kKeeperflag = 53;
+ const static uint16 kLasttrigger = 54;
+ const static uint16 kMandead = 55;
+ const static uint16 kSeed = 56;
+ const static uint16 kNeedtotravel = 59;
+ const static uint16 kThroughdoor = 60;
+ const static uint16 kNewobs = 61;
+ const static uint16 kRyanon = 62;
+ const static uint16 kCombatcount = 63;
+ const static uint16 kLastweapon = 64;
+ const static uint16 kDreamnumber = 65;
+ const static uint16 kRoomafterdream = 66;
+ const static uint16 kShakecounter = 67;
+ const static uint16 kSpeechcount = 68;
+ const static uint16 kCharshift = 69;
+ const static uint16 kKerning = 71;
+ const static uint16 kBrightness = 72;
+ const static uint16 kRoomloaded = 73;
+ const static uint16 kDidzoom = 74;
+ const static uint16 kLinespacing = 75;
+ const static uint16 kTextaddressx = 77;
+ const static uint16 kTextaddressy = 79;
+ const static uint16 kTextlen = 81;
+ const static uint16 kLastxpos = 82;
+ const static uint16 kIcontop = 84;
+ const static uint16 kIconleft = 86;
+ const static uint16 kItemframe = 88;
+ const static uint16 kItemtotran = 89;
+ const static uint16 kRoomad = 90;
+ const static uint16 kOldsubject = 92;
+ const static uint16 kWithobject = 94;
+ const static uint16 kWithtype = 95;
+ const static uint16 kLookcounter = 96;
+ const static uint16 kCommand = 98;
+ const static uint16 kCommandtype = 99;
+ const static uint16 kOldcommandtype = 100;
+ const static uint16 kObjecttype = 101;
+ const static uint16 kGetback = 102;
+ const static uint16 kInvopen = 103;
+ const static uint16 kMainmode = 104;
+ const static uint16 kPickup = 105;
+ const static uint16 kLastinvpos = 106;
+ const static uint16 kExamagain = 107;
+ const static uint16 kNewtextline = 108;
+ const static uint16 kOpenedob = 109;
+ const static uint16 kOpenedtype = 110;
+ const static uint16 kOldmapadx = 111;
+ const static uint16 kOldmapady = 113;
+ const static uint16 kMapadx = 115;
+ const static uint16 kMapady = 117;
+ const static uint16 kMapoffsetx = 119;
+ const static uint16 kMapoffsety = 121;
+ const static uint16 kMapxstart = 123;
+ const static uint16 kMapystart = 125;
+ const static uint16 kMapxsize = 127;
+ const static uint16 kMapysize = 128;
+ const static uint16 kHavedoneobs = 129;
+ const static uint16 kManisoffscreen = 130;
+ const static uint16 kRainspace = 131;
+ const static uint16 kFacing = 132;
+ const static uint16 kLeavedirection = 133;
+ const static uint16 kTurntoface = 134;
+ const static uint16 kTurndirection = 135;
+ const static uint16 kMaintimer = 136;
+ const static uint16 kIntrocount = 138;
+ const static uint16 kArrowad = 139;
+ const static uint16 kCurrentkey = 141;
+ const static uint16 kOldkey = 142;
+ const static uint16 kUseddirection = 143;
+ const static uint16 kCurrentkey2 = 144;
+ const static uint16 kTimercount = 145;
+ const static uint16 kOldtimercount = 146;
+ const static uint16 kMapx = 147;
+ const static uint16 kMapy = 148;
+ const static uint16 kNewscreen = 149;
+ const static uint16 kRyanx = 150;
+ const static uint16 kRyany = 151;
+ const static uint16 kLastflag = 152;
+ const static uint16 kLastflagex = 153;
+ const static uint16 kFlagx = 154;
+ const static uint16 kFlagy = 155;
+ const static uint16 kCurrentex = 156;
+ const static uint16 kCurrentfree = 157;
+ const static uint16 kCurrentframe = 158;
+ const static uint16 kFramesad = 160;
+ const static uint16 kDataad = 162;
+ const static uint16 kFrsegment = 164;
+ const static uint16 kObjectx = 166;
+ const static uint16 kObjecty = 168;
+ const static uint16 kOffsetx = 170;
+ const static uint16 kOffsety = 172;
+ const static uint16 kSavesize = 174;
+ const static uint16 kSavesource = 176;
+ const static uint16 kSavex = 178;
+ const static uint16 kSavey = 179;
+ const static uint16 kCurrentob = 180;
+ const static uint16 kPriority = 181;
+ const static uint16 kDestpos = 182;
+ const static uint16 kReallocation = 183;
+ const static uint16 kRoomnum = 184;
+ const static uint16 kNowinnewroom = 185;
+ const static uint16 kResetmanxy = 186;
+ const static uint16 kNewlocation = 187;
+ const static uint16 kAutolocation = 188;
+ const static uint16 kMustload = 189;
+ const static uint16 kAnswered = 190;
+ const static uint16 kSaidno = 191;
+ const static uint16 kDoorcheck1 = 192;
+ const static uint16 kDoorcheck2 = 193;
+ const static uint16 kDoorcheck3 = 194;
+ const static uint16 kDoorcheck4 = 195;
+ const static uint16 kMousex = 196;
+ const static uint16 kMousey = 198;
+ const static uint16 kMousebutton = 200;
+ const static uint16 kMousebutton1 = 202;
+ const static uint16 kMousebutton2 = 204;
+ const static uint16 kMousebutton3 = 206;
+ const static uint16 kMousebutton4 = 208;
+ const static uint16 kOldbutton = 210;
+ const static uint16 kOldx = 212;
+ const static uint16 kOldy = 214;
+ const static uint16 kLastbutton = 216;
+ const static uint16 kOldpointerx = 218;
+ const static uint16 kOldpointery = 220;
+ const static uint16 kDelherex = 222;
+ const static uint16 kDelherey = 224;
+ const static uint16 kPointerxs = 226;
+ const static uint16 kPointerys = 227;
+ const static uint16 kDelxs = 228;
+ const static uint16 kDelys = 229;
+ const static uint16 kPointerframe = 230;
+ const static uint16 kPointerpower = 231;
+ const static uint16 kAuxpointerframe = 232;
+ const static uint16 kPointermode = 233;
+ const static uint16 kPointerspeed = 234;
+ const static uint16 kPointercount = 235;
+ const static uint16 kInmaparea = 236;
+ const static uint16 kReelpointer = 237;
+ const static uint16 kSlotdata = 239;
+ const static uint16 kThisslot = 240;
+ const static uint16 kSlotflags = 241;
+ const static uint16 kTakeoff = 242;
+ const static uint16 kTalkmode = 244;
+ const static uint16 kTalkpos = 245;
+ const static uint16 kCharacter = 246;
+ const static uint16 kPersondata = 247;
+ const static uint16 kTalknum = 249;
+ const static uint16 kNumberinroom = 250;
+ const static uint16 kCurrentcel = 251;
+ const static uint16 kOldselection = 252;
+ const static uint16 kStopwalking = 253;
+ const static uint16 kMouseon = 254;
+ const static uint16 kPlayed = 255;
+ const static uint16 kTimer1 = 257;
+ const static uint16 kTimer2 = 258;
+ const static uint16 kTimer3 = 259;
+ const static uint16 kWholetimer = 260;
+ const static uint16 kTimer1to = 262;
+ const static uint16 kTimer2to = 263;
+ const static uint16 kTimer3to = 264;
+ const static uint16 kWatchdump = 265;
+ const static uint16 kCurrentset = 266;
+ const static uint16 kLogonum = 268;
+ const static uint16 kOldlogonum = 269;
+ const static uint16 kNewlogonum = 270;
+ const static uint16 kNetseg = 271;
+ const static uint16 kNetpoint = 273;
+ const static uint16 kKeynum = 275;
+ const static uint16 kCursorstate = 276;
+ const static uint16 kPressed = 277;
+ const static uint16 kPresspointer = 278;
+ const static uint16 kGraphicpress = 280;
+ const static uint16 kPresscount = 281;
+ const static uint16 kKeypadax = 282;
+ const static uint16 kKeypadcx = 284;
+ const static uint16 kLightcount = 286;
+ const static uint16 kFolderpage = 287;
+ const static uint16 kDiarypage = 288;
+ const static uint16 kMenucount = 289;
+ const static uint16 kSymboltopx = 290;
+ const static uint16 kSymboltopnum = 291;
+ const static uint16 kSymboltopdir = 292;
+ const static uint16 kSymbolbotx = 293;
+ const static uint16 kSymbolbotnum = 294;
+ const static uint16 kSymbolbotdir = 295;
+ const static uint16 kSymboltolight = 296;
+ const static uint16 kSymbol1 = 297;
+ const static uint16 kSymbol2 = 298;
+ const static uint16 kSymbol3 = 299;
+ const static uint16 kSymbolnum = 300;
+ const static uint16 kDumpx = 301;
+ const static uint16 kDumpy = 303;
+ const static uint16 kWalkandexam = 305;
+ const static uint16 kWalkexamtype = 306;
+ const static uint16 kWalkexamnum = 307;
+ const static uint16 kCursloc = 308;
+ const static uint16 kCurslocx = 310;
+ const static uint16 kCurslocy = 312;
+ const static uint16 kCurpos = 314;
+ const static uint16 kMonadx = 316;
+ const static uint16 kMonady = 318;
+ const static uint16 kGotfrom = 320;
+ const static uint16 kMonsource = 322;
+ const static uint16 kNumtodo = 324;
+ const static uint16 kTimecount = 326;
+ const static uint16 kCounttotimed = 328;
+ const static uint16 kTimedseg = 330;
+ const static uint16 kTimedoffset = 332;
+ const static uint16 kTimedy = 334;
+ const static uint16 kTimedx = 335;
+ const static uint16 kNeedtodumptimed = 336;
+ const static uint16 kHandle = 337;
+ const static uint16 kLoadingorsave = 339;
+ const static uint16 kCurrentslot = 340;
+ const static uint16 kCursorpos = 341;
+ const static uint16 kColourpos = 342;
+ const static uint16 kFadedirection = 343;
+ const static uint16 kNumtofade = 344;
+ const static uint16 kFadecount = 345;
+ const static uint16 kAddtogreen = 346;
+ const static uint16 kAddtored = 347;
+ const static uint16 kAddtoblue = 348;
+ const static uint16 kLastsoundreel = 349;
+ const static uint16 kSoundbuffer = 351;
+ const static uint16 kSoundbufferad = 353;
+ const static uint16 kSoundbufferpage = 355;
+ const static uint16 kSoundtimes = 356;
+ const static uint16 kNeedsoundbuff = 357;
+ const static uint16 kOldint9seg = 358;
+ const static uint16 kOldint9add = 360;
+ const static uint16 kOldint8seg = 362;
+ const static uint16 kOldint8add = 364;
+ const static uint16 kOldsoundintseg = 366;
+ const static uint16 kOldsoundintadd = 368;
+ const static uint16 kSoundbaseadd = 370;
+ const static uint16 kDsp_status = 372;
+ const static uint16 kDsp_write = 374;
+ const static uint16 kDmaaddress = 376;
+ const static uint16 kSoundint = 377;
+ const static uint16 kSounddmachannel = 378;
+ const static uint16 kSampleplaying = 379;
+ const static uint16 kTestresult = 380;
+ const static uint16 kCurrentirq = 381;
+ const static uint16 kSpeechloaded = 382;
+ const static uint16 kSpeechlength = 383;
+ const static uint16 kVolume = 385;
+ const static uint16 kVolumeto = 386;
+ const static uint16 kVolumedirection = 387;
+ const static uint16 kVolumecount = 388;
+ const static uint16 kPlayblock = 389;
+ const static uint16 kWongame = 390;
+ const static uint16 kLasthardkey = 391;
+ const static uint16 kBufferin = 392;
+ const static uint16 kBufferout = 394;
+ const static uint16 kExtras = 396;
+ const static uint16 kWorkspace = 398;
+ const static uint16 kMapstore = 400;
+ const static uint16 kCharset1 = 402;
+ const static uint16 kTempcharset = 404;
+ const static uint16 kIcons1 = 406;
+ const static uint16 kIcons2 = 408;
+ const static uint16 kBuffers = 410;
+ const static uint16 kMainsprites = 412;
+ const static uint16 kBackdrop = 414;
+ const static uint16 kMapdata = 416;
+ const static uint16 kSounddata = 418;
+ const static uint16 kSounddata2 = 420;
+ const static uint16 kRecordspace = 422;
+ const static uint16 kFreedat = 424;
+ const static uint16 kSetdat = 426;
+ const static uint16 kReel1 = 428;
+ const static uint16 kReel2 = 430;
+ const static uint16 kReel3 = 432;
+ const static uint16 kRoomdesc = 434;
+ const static uint16 kFreedesc = 436;
+ const static uint16 kSetdesc = 438;
+ const static uint16 kBlockdesc = 440;
+ const static uint16 kSetframes = 442;
+ const static uint16 kFreeframes = 444;
+ const static uint16 kPeople = 446;
+ const static uint16 kReels = 448;
+ const static uint16 kCommandtext = 450;
+ const static uint16 kPuzzletext = 452;
+ const static uint16 kTraveltext = 454;
+ const static uint16 kTempgraphics = 456;
+ const static uint16 kTempgraphics2 = 458;
+ const static uint16 kTempgraphics3 = 460;
+ const static uint16 kTempsprites = 462;
+ const static uint16 kTextfile1 = 464;
+ const static uint16 kTextfile2 = 466;
+ const static uint16 kTextfile3 = 468;
+ const static uint16 kBlinkframe = 470;
+ const static uint16 kBlinkcount = 471;
+ const static uint16 kReasseschanges = 472;
+ const static uint16 kPointerspath = 473;
+ const static uint16 kManspath = 474;
+ const static uint16 kPointerfirstpath = 475;
+ const static uint16 kFinaldest = 476;
+ const static uint16 kDestination = 477;
+ const static uint16 kLinestartx = 478;
+ const static uint16 kLinestarty = 480;
+ const static uint16 kLineendx = 482;
+ const static uint16 kLineendy = 484;
+ const static uint16 kIncrement1 = 486;
+ const static uint16 kIncrement2 = 488;
+ const static uint16 kLineroutine = 490;
+ const static uint16 kLinepointer = 491;
+ const static uint16 kLinedirection = 492;
+ const static uint16 kLinelength = 493;
+ const static uint16 kLiftsoundcount = 494;
+ const static uint16 kEmmhandle = 495;
+ const static uint16 kEmmpageframe = 497;
+ const static uint16 kEmmhardwarepage = 499;
+ const static uint16 kCh0emmpage = 500;
+ const static uint16 kCh0offset = 502;
+ const static uint16 kCh0blockstocopy = 504;
+ const static uint16 kCh0playing = 506;
+ const static uint16 kCh0repeat = 507;
+ const static uint16 kCh0oldemmpage = 508;
+ const static uint16 kCh0oldoffset = 510;
+ const static uint16 kCh0oldblockstocopy = 512;
+ const static uint16 kCh1playing = 514;
+ const static uint16 kCh1emmpage = 515;
+ const static uint16 kCh1offset = 517;
+ const static uint16 kCh1blockstocopy = 519;
+ const static uint16 kCh1blocksplayed = 521;
+ const static uint16 kSoundbufferwrite = 523;
+ const static uint16 kSoundemmpage = 525;
+ const static uint16 kSpeechemmpage = 527;
+ const static uint16 kCurrentsample = 529;
+ const static uint16 kRoomssample = 530;
+ const static uint16 kGameerror = 531;
+ const static uint16 kHowmuchalloc = 532;
+ const static uint16 kReelroutines = 534;
+ const static uint16 kReelcalls = 991;
+ const static uint16 kRoombyroom = 1214;
+ const static uint16 kR0 = 1326;
+ const static uint16 kR1 = 1327;
+ const static uint16 kR2 = 1331;
+ const static uint16 kR6 = 1350;
+ const static uint16 kR8 = 1357;
+ const static uint16 kR9 = 1373;
+ const static uint16 kR10 = 1380;
+ const static uint16 kR11 = 1384;
+ const static uint16 kR12 = 1388;
+ const static uint16 kR13 = 1392;
+ const static uint16 kR14 = 1405;
+ const static uint16 kR20 = 1439;
+ const static uint16 kR22 = 1461;
+ const static uint16 kR23 = 1492;
+ const static uint16 kR25 = 1505;
+ const static uint16 kR26 = 1527;
+ const static uint16 kR27 = 1549;
+ const static uint16 kR28 = 1574;
+ const static uint16 kR29 = 1593;
+ const static uint16 kR45 = 1609;
+ const static uint16 kR46 = 1616;
+ const static uint16 kR47 = 1653;
+ const static uint16 kR52 = 1666;
+ const static uint16 kR53 = 1670;
+ const static uint16 kR55 = 1677;
+ const static uint16 kSpritename1 = 1819;
+ const static uint16 kSpritename3 = 1832;
+ const static uint16 kIdname = 1845;
+ const static uint16 kCharacterset1 = 1857;
+ const static uint16 kCharacterset2 = 1870;
+ const static uint16 kCharacterset3 = 1883;
+ const static uint16 kSamplename = 1896;
+ const static uint16 kBasicsample = 1909;
+ const static uint16 kIcongraphics0 = 1922;
+ const static uint16 kIcongraphics1 = 1935;
+ const static uint16 kExtragraphics1 = 1948;
+ const static uint16 kIcongraphics8 = 1961;
+ const static uint16 kMongraphicname = 1974;
+ const static uint16 kMongraphics2 = 1987;
+ const static uint16 kCityname = 2000;
+ const static uint16 kTravelgraphic1 = 2013;
+ const static uint16 kTravelgraphic2 = 2026;
+ const static uint16 kDiarygraphic = 2039;
+ const static uint16 kMonitorfile1 = 2052;
+ const static uint16 kMonitorfile2 = 2065;
+ const static uint16 kMonitorfile10 = 2078;
+ const static uint16 kMonitorfile11 = 2091;
+ const static uint16 kMonitorfile12 = 2104;
+ const static uint16 kMonitorfile13 = 2117;
+ const static uint16 kMonitorfile20 = 2130;
+ const static uint16 kMonitorfile21 = 2143;
+ const static uint16 kMonitorfile22 = 2156;
+ const static uint16 kMonitorfile23 = 2169;
+ const static uint16 kMonitorfile24 = 2182;
+ const static uint16 kFoldertext = 2195;
+ const static uint16 kDiarytext = 2208;
+ const static uint16 kPuzzletextname = 2221;
+ const static uint16 kTraveltextname = 2234;
+ const static uint16 kIntrotextname = 2247;
+ const static uint16 kEndtextname = 2260;
+ const static uint16 kCommandtextname = 2273;
+ const static uint16 kVolumetabname = 2286;
+ const static uint16 kFoldergraphic1 = 2299;
+ const static uint16 kFoldergraphic2 = 2312;
+ const static uint16 kFoldergraphic3 = 2325;
+ const static uint16 kSymbolgraphic = 2338;
+ const static uint16 kGungraphic = 2351;
+ const static uint16 kMonkface = 2364;
+ const static uint16 kTitle0graphics = 2377;
+ const static uint16 kTitle1graphics = 2390;
+ const static uint16 kTitle2graphics = 2403;
+ const static uint16 kTitle3graphics = 2416;
+ const static uint16 kTitle4graphics = 2429;
+ const static uint16 kTitle5graphics = 2442;
+ const static uint16 kTitle6graphics = 2455;
+ const static uint16 kTitle7graphics = 2468;
+ const static uint16 kPalettescreen = 2481;
+ const static uint16 kCurrentfile = 2970;
+ const static uint16 kDmaaddresses = 5118;
+ const static uint16 kFileheader = 6091;
+ const static uint16 kFiledata = 6141;
+ const static uint16 kExtradata = 6181;
+ const static uint16 kRoomdata = 6187;
+ const static uint16 kMadeuproomdat = 7979;
+ const static uint16 kRoomscango = 8011;
+ const static uint16 kRoompics = 8027;
+ const static uint16 kOplist = 8042;
+ const static uint16 kInputline = 8045;
+ const static uint16 kLinedata = 8173;
+ const static uint16 kPresslist = 8573;
+ const static uint16 kSavenames = 8579;
+ const static uint16 kSavefiles = 8698;
+ const static uint16 kRecname = 8789;
+ const static uint16 kQuitrequested = 8802;
+ const static uint16 kSubtitles = 8803;
+ const static uint16 kForeignrelease = 8804;
+ const static uint16 kStak = 8805;
+ const static uint16 kBlocktextdat = (0);
+ const static uint16 kPersonframes = (0);
+ const static uint16 kDebuglevel1 = (0);
+ const static uint16 kDebuglevel2 = (0);
+ const static uint16 kPlayback = (0);
+ const static uint16 kMap = (0);
+ const static uint16 kSettextdat = (0);
+ const static uint16 kSpanish = (0);
+ const static uint16 kFramedata = (0);
+ const static uint16 kRecording = (0);
+ const static uint16 kFlags = (0);
+ const static uint16 kGerman = (0);
+ const static uint16 kTextunder = (0);
+ const static uint16 kPathdata = (0);
+ const static uint16 kDemo = (0);
+ const static uint16 kExframedata = (0);
+ const static uint16 kIntextdat = (0);
+ const static uint16 kFreetextdat = (0);
+ const static uint16 kFrframedata = (0);
+ const static uint16 kSettext = (0+(130*2));
+ const static uint16 kOpeninvlist = (0+(228*13));
+ const static uint16 kRyaninvlist = (0+(228*13)+32);
+ const static uint16 kPointerback = (0+(228*13)+32+60);
+ const static uint16 kMapflags = (0+(228*13)+32+60+(32*32));
+ const static uint16 kStartpal = (0+(228*13)+32+60+(32*32)+(11*10*3));
+ const static uint16 kEndpal = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
+ const static uint16 kMaingamepal = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768);
+ const static uint16 kSpritetable = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
+ const static uint16 kSetlist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32));
+ const static uint16 kFreelist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5));
+ const static uint16 kExlist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5));
+ const static uint16 kPeoplelist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5));
+ const static uint16 kZoomspace = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5));
+ const static uint16 kPrintedlist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40));
+ const static uint16 kListofchanges = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80));
+ const static uint16 kUndertimedtext = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4));
+ const static uint16 kRainlist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30));
+ const static uint16 kInitialreelrouts = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64));
+ const static uint16 kInitialvars = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+991-534);
+ const static uint16 kLengthofbuffer = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+991-534+68-0);
+ const static uint16 kReellist = (0+(36*144));
+ const static uint16 kIntext = (0+(38*2));
+ const static uint16 kLengthofmap = (0+(66*60));
+ const static uint16 kFreetext = (0+(82*2));
+ const static uint16 kBlocktext = (0+(98*2));
+ const static uint16 kBlocks = (0+192);
+ const static uint16 kFrframes = (0+2080);
+ const static uint16 kExframes = (0+2080);
+ const static uint16 kFrames = (0+2080);
+ const static uint16 kExdata = (0+2080+30000);
+ const static uint16 kExtextdat = (0+2080+30000+(16*114));
+ const static uint16 kExtext = (0+2080+30000+(16*114)+((114+2)*2));
+ const static uint16 kLengthofextra = (0+2080+30000+(16*114)+((114+2)*2)+18000);
+ const static uint16 kPersontxtdat = (0+24);
+ const static uint16 kPersontext = (0+24+(1026*2));
+ const static uint16 kInputport = (0x63);
+ const static uint16 kForeign = (1);
+ const static uint16 kCd = (1);
+ const static uint16 kNumexobjects = (114);
+ const static uint16 kUndertextsizey = (13);
+ const static uint16 kZoomy = (132);
+ const static uint16 kFreedatlen = (16*80);
+ const static uint16 kExtextlen = (18000);
+ const static uint16 kLenofmapstore = (22*8*20*8);
+ const static uint16 kUndertextsizex = (228);
+ const static uint16 kNumchanges = (250);
+ const static uint16 kUndertimedysize = (30);
+ const static uint16 kExframeslen = (30000);
+ const static uint16 kTablesize = (32);
+ const static uint16 kScreenwidth = (320);
+ const static uint16 kKeypadx = (36+112);
+ const static uint16 kItempicsize = (44);
+ const static uint16 kDiaryy = (48+12);
+ const static uint16 kOpsy = (52);
+ const static uint16 kSymboly = (56);
+ const static uint16 kInventy = (58);
+ const static uint16 kMenuy = (60);
+ const static uint16 kOpsx = (60);
+ const static uint16 kMaplength = (60);
+ const static uint16 kHeaderlen = (6187-6091);
+ const static uint16 kSymbolx = (64);
+ const static uint16 kSetdatlen = (64*128);
+ const static uint16 kMapwidth = (66);
+ const static uint16 kTextstart = (66*2);
+ const static uint16 kMaplen = (66*60);
+ const static uint16 kDiaryx = (68+24);
+ const static uint16 kLengthofvars = (68-0);
+ const static uint16 kKeypady = (72);
+ const static uint16 kZoomx = (8);
+ const static uint16 kInventx = (80);
+ const static uint16 kMenux = (80+40);
+ const static uint16 kLenofreelrouts = (991-534);
+
+ void bothchannels();
+ void usewire();
+ void getnamepos();
+ void drawitall();
+ void clearstartpal();
+ void femalefan();
+ void greyscalesum();
+ void showgamereel();
+ void identifyob();
+ void trysoundalloc();
+ void uselighter();
+ void showmenu();
+ void usepoolreader();
+ void showgroup();
+ void startdmablock();
+ void useopenbox();
+ void clearbuffers();
+ void neterror();
+ void storeit();
+ void lockeddoorway();
+ void isitworn();
+ void putundertimed();
+ void dumpmap();
+ void multidump();
+ void channel0only();
+ void worktoscreenm();
+ void removeemm();
+ void mansatstill();
+ void getobtextstart();
+ void loadfolder();
+ void decide();
+ void dumppointer();
+ void reelsonscreen();
+ void getridofreels();
+ void readkey();
+ void louis();
+ void entrytexts();
+ void getreelstart();
+ void buttonenter();
+ void checkinput();
+ void crosshair();
+ void bresenhams();
+ void getbackfromops();
+ void frameoutv();
+ void restoreall();
+ void screenupdate();
+ void addlength();
+ void usetimedtext();
+ void putundercentre();
+ void checkobjectsize();
+ void commandonly();
+ void adjustlen();
+ void deallocatemem();
+ void mainscreen();
+ void watchreel();
+ void showfolder();
+ void turnanypathoff();
+ void openfilefromc();
+ void gettime();
+ void clearwork();
+ void loadtraveltext();
+ void worktoscreen();
+ void getexpos();
+ void fadedos();
+ void multiget();
+ void fadeupmonfirst();
+ void drawfloor();
+ void loadkeypad();
+ void findsource();
+ void clearendpal();
+ void findtext1();
+ void isryanholding();
+ void interupttest();
+ void usecashcard();
+ void usewall();
+ void opentomb();
+ void buttonfour();
+ void animpointer();
+ void lockmon();
+ void dochange();
+ void getanyaddir();
+ void showsaveops();
+ void intromonks1();
+ void resetlocation();
+ void oldtonames();
+ void showdiscops();
+ void advisor();
+ void additionaltext();
+ void kernchars();
+ void othersmoker();
+ void autosetwalk();
+ void setuptimedtemp();
+ void blocknametext();
+ void useelevator5();
+ void useelevator4();
+ void useelevator1();
+ void attendant();
+ void useelevator3();
+ void useelevator2();
+ void buttonone();
+ void keyboardread();
+ void deltextline();
+ void entercode();
+ void getopenedsize();
+ void getpersframe();
+ void doshake();
+ void resetkeyboard();
+ void showpanel();
+ void soundstartup();
+ void slabdoora();
+ void fadeupyellows();
+ void slabdoorc();
+ void slabdoorb();
+ void slabdoore();
+ void slabdoord();
+ void adjustup();
+ void readsetdata();
+ void loadintotemp();
+ void loadintroroom();
+ void saveseg();
+ void showblink();
+ void mousecall();
+ void train();
+ void watchcount();
+ void fadedownmon();
+ void loadcart();
+ void splitintolines();
+ void bartender();
+ void eden();
+ void showdiary();
+ void purgealocation();
+ void updatepeople();
+ void slabdoorf();
+ void addtopeoplelist();
+ void hangoncurs();
+ void sparkydrip();
+ void modifychar();
+ void compare();
+ void printcurs();
+ void convertkey();
+ void outofopen();
+ void dealwithspecial();
+ void dircom();
+ void liftsprite();
+ void dumpkeypad();
+ void dumpzoom();
+ void endgameseq();
+ void cancelch0();
+ void setbotleft();
+ void findfirstpath();
+ void showallfree();
+ void loadold();
+ void loadtempcharset();
+ void useslab();
+ void aboutturn();
+ void usealtar();
+ void createpanel2();
+ void turnonpower();
+ void manasleep2();
+ void moretalk();
+ void printslow();
+ void loadroom();
+ void starttalk();
+ void delchar();
+ void getanyad();
+ void endgame();
+ void monprint();
+ void usepipe();
+ void startloading();
+ void getunderzoom();
+ void candles();
+ void backobject();
+ void rollendcredits2();
+ void reminders();
+ void selectslot2();
+ void runtap();
+ void domix();
+ void priesttext();
+ void paneltomap();
+ void obname();
+ void getridoftemp3();
+ void getridoftemp2();
+ void usebalcony();
+ void runendseq();
+ void dumpdiarykeys();
+ void disablesoundint();
+ void checkifset();
+ void showallex();
+ void showrain();
+ void openpoolboss();
+ void buttontwo();
+ void fillopen();
+ void delsprite();
+ void getroomspaths();
+ void dumptextline();
+ void fadescreendownhalf();
+ void useplate();
+ void candles1();
+ void lookininterface();
+ void manasleep();
+ void isitdescribed();
+ void hotelbell();
+ void loadspeech();
+ void cls();
+ void printsprites();
+ void dumptimedtext();
+ void showallobs();
+ void getnumber();
+ void adjustleft();
+ void calledenslift();
+ void useclearbox();
+ void entryanims();
+ void nextfolder();
+ void getfreead();
+ void showarrows();
+ void walkintoroom();
+ void getridoftemptext();
+ void printoutermon();
+ void setuppit();
+ void showpcx();
+ void showdecisions();
+ void checkspeed();
+ void printchar();
+ void showkeypad();
+ void obtoinv();
+ void removeobfrominv();
+ void usecoveredbox();
+ void openyourneighbour();
+ void fadescreenuphalf();
+ void getridoftempcharset();
+ void heavy();
+ void endpaltostart();
+ void showkeys();
+ void usekey();
+ void locklighton();
+ void useladderb();
+ void spriteupdate();
+ void usetempcharset();
+ void discops();
+ void printdirect();
+ void delthisone();
+ void makebackob();
+ void middlepanel();
+ void dumpwatch();
+ void saveload();
+ void monitorlogo();
+ void loadposition();
+ void wornerror();
+ void entersymbol();
+ void showword();
+ void dirfile();
+ void setmode();
+ void walktotext();
+ void pickupconts();
+ void locklightoff();
+ void wearwatch();
+ void runintroseq();
+ void doblocks();
+ void showbyte();
+ void allpalette();
+ void findormake();
+ void nextsymbol();
+ void monks2text();
+ void poolguard();
+ void clearpalette();
+ void cantdrop();
+ void maptopanel();
+ void calcmapad();
+ void getridofall();
+ void copper();
+ void folderhints();
+ void openhoteldoor();
+ void removesetobject();
+ void checkifperson();
+ void frameoutfx();
+ void blank();
+ void drinker();
+ void nextcolon();
+ void placefreeobject();
+ void delpointer();
+ void loopchannel0();
+ void initrain();
+ void showleftpage();
+ void rockstar();
+ void adjustright();
+ void putunderzoom();
+ void vsync();
+ void turnpathoff();
+ void findinvpos();
+ void usetext();
+ void hangonpq();
+ void liftnoise();
+ void workoutframes();
+ void getbackfromob();
+ void dumpsymbox();
+ void loadgame();
+ void getridoftemp();
+ void showcity();
+ void dumpsymbol();
+ void disablepath();
+ void buttonsix();
+ void intro2text();
+ void showouterpad();
+ void getkeyandlogo();
+ void selectob();
+ void checkcoords();
+ void dumpmenu();
+ void chewy();
+ void accesslighton();
+ void dosreturn();
+ void titles();
+ void quickquit();
+ void showpointer();
+ void usecooker();
+ void loadmenu();
+ void checkforemm();
+ void checkifpathison();
+ void smallcandle();
+ void receptionist();
+ void selectslot();
+ void edenscdplayer();
+ void readoneblock();
+ void fadeupmon();
+ void paltoendpal();
+ void fadetowhite();
+ void textformonk();
+ void loadsavebox();
+ void fadescreenup();
+ void soundend();
+ void redes();
+ void errormessage1();
+ void clearchanges();
+ void errormessage3();
+ void deletetaken();
+ void putundermenu();
+ void checkifex();
+ void intromagic2();
+ void findobname();
+ void edeninbath();
+ void intromagic1();
+ void showdiarypage();
+ void useshield();
+ void getbacktoops();
+ void rollendcredits();
+ void intro1text();
+ void getmapad();
+ void playchannel1();
+ void playchannel0();
+ void usemon();
+ void steady();
+ void pixelcheckset();
+ void reexfrominv();
+ void fillspace();
+ void talk();
+ void usedryer();
+ void dumpeverything();
+ void usehatch();
+ void zoom();
+ void outofinv();
+ void viewfolder();
+ void walking();
+ void diarykeyp();
+ void readabyte();
+ void showframe();
+ void random();
+ void obicons();
+ void frameoutbh();
+ void channel1only();
+ void playguitar();
+ void lastfolder();
+ void transfermap();
+ void showreelframe();
+ void showmonk();
+ void diarykeyn();
+ void set16colpalette();
+ void convicons();
+ void interviewer();
+ void sparky();
+ void purgeanitem();
+ void madman();
+ void createpanel();
+ void turnpathon();
+ void showmainops();
+ void madmanstelly();
+ void constant();
+ void loadroomssample();
+ void getblockofpixel();
+ void paltostartpal();
+ void bossman();
+ void getridofpit();
+ void convnum();
+ void nothelderror();
+ void readheader();
+ void getsetad();
+ void getyad();
+ void reconstruct();
+ void soldier1();
+ void getundercentre();
+ void checkforexit();
+ void loadseg();
+ void makeheader();
+ void setkeyboardint();
+ void priest();
+ void readmouse();
+ void powerlighton();
+ void savefilewrite();
+ void printmessage2();
+ void loadnews();
+ void rollem();
+ void makeworn();
+ void examineobtext();
+ void startup();
+ void savegame();
+ void startpaltoend();
+ void showicon();
+ void findopenpos();
+ void describeob();
+ void deleteexframe();
+ void folderexit();
+ void useplinth();
+ void wheelsound();
+ void actualsave();
+ void autolook();
+ void checkbasemem();
+ void transfertext();
+ void searchforsame();
+ void enablesoundint();
+ void getback1();
+ void setlocation();
+ void fadefromwhite();
+ void checksoundint();
+ void usewindow();
+ void wearshades();
+ void onedigit();
+ void pitinterupt();
+ void deleverything();
+ void fadescreendown();
+ void findxyfrompath();
+ void namestoold();
+ void getxad();
+ void openinv();
+ void lookatplace();
+ void useaxe();
+ void examineob();
+ void buttonnought();
+ void useelvdoor();
+ void putbackobstuff();
+ void useladder();
+ void realcredits();
+ void handclap();
+ void smokebloke();
+ void showexit();
+ void printundermon();
+ void buttonnine();
+ void findallopen();
+ void loadintotemp3();
+ void loadintotemp2();
+ void gamer();
+ void personnametext();
+ void quitsymbol();
+ void readfromfile();
+ void initialinv();
+ void showslots();
+ void dofade();
+ void hangon();
+ void settopright();
+ void findsetobject();
+ void singlekey();
+ void seecommandtail();
+ void getundertimed();
+ void hangone();
+ void carparkdrip();
+ void usediary();
+ void deleteexobject();
+ void frameoutnm();
+ void moneypoke();
+ void destselect();
+ void restoreems();
+ void lastdest();
+ void removefreeobject();
+ void trapdoor();
+ void openlouis();
+ void buttonthree();
+ void getundermenu();
+ void randomnumber();
+ void lookatcard();
+ void helicopter();
+ void scrollmonitor();
+ void setsoundoff();
+ void setpickup();
+ void dropobject();
+ void printmessage();
+ void reexfromopen();
+ void fillryan();
+ void loadtemptext();
+ void usestereo();
+ void showcurrentfile();
+ void copyname();
+ void look();
+ void setmouse();
+ void checkone();
+ void transferinv();
+ void candles2();
+ void pickupob();
+ void error();
+ void showopbox();
+ void clearbeforeload();
+ void biblequote();
+ void doload();
+ void afterintroroom();
+ void blockget();
+ void usetrainer();
+ void allocatework();
+ void addtopresslist();
+ void walkandexamine();
+ void dmaend();
+ void quickquit2();
+ void twodigitnum();
+ void madmantext();
+ void dumpcurrent();
+ void textforend();
+ void showdiarykeys();
+ void dontloadseg();
+ void madmode();
+ void intro3text();
+ void allocatemem();
+ void sortoutmap();
+ void doorway();
+ void useopened();
+ void inventory();
+ void powerlightoff();
+ void getroomdata();
+ void showoutermenu();
+ void signon();
+ void deleteextext();
+ void foghornsound();
+ void showrightpage();
+ void openhoteldoor2();
+ void examicon();
+ void showgun();
+ void switchryanon();
+ void louischair();
+ void saveems();
+ void locationpic();
+ void getflagunderp();
+ void dolook();
+ void opentvdoor();
+ void triggermessage();
+ void finalframe();
+ void plotreel();
+ void swapwithopen();
+ void makesprite();
+ void dreamweb();
+ void droperror();
+ void openfilenocheck();
+ void calledensdlift();
+ void checkinside();
+ void gates();
+ void selectlocation();
+ void showwatch();
+ void turnanypathon();
+ void restorereels();
+ void setwalk();
+ void printboth();
+ void useroutine();
+ void zoomicon();
+ void hotelcontrol();
+ void findpathofpoint();
+ void issetobonmap();
+ void getdestinfo();
+ void drunk();
+ void dumpblink();
+ void setuptimeduse();
+ void grafittidoor();
+ void input();
+ void nextdest();
+ void getdimension();
+ void makecaps();
+ void read();
+ void fadescreenups();
+ void checkdest();
+ void initman();
+ void loadpalfromiff();
+ void facerightway();
+ void startup1();
+ void findlen();
+ void showsymbol();
+ void mugger();
+ void atmospheres();
+ void out22c();
+ void loadpersonal();
+ void gettingshot();
+ void settopleft();
+ void searchforstring();
+ void clearsprites();
+ void obpicture();
+ void selectopenob();
+ void widedoor();
+ void security();
+ void printasprite();
+ void buttonfive();
+ void soundonreels();
+ void usegun();
+ void autoappear();
+ void findnextcolon();
+ void readmouse4();
+ void openryan();
+ void readmouse1();
+ void showman();
+ void readmouse2();
+ void newplace();
+ void movemap();
+ void loadsample();
+ void usecardreader1();
+ void usecardreader2();
+ void usecardreader3();
+ void tattooman();
+ void usehandle();
+ void quitkey();
+ void openfile();
+ void usecharset1();
+ void makenextblock();
+ void showpuztext();
+ void addalong();
+ void width160();
+ void incryanpage();
+ void dodoor();
+ void eraseoldobs();
+ void buttoneight();
+ void opensarters();
+ void findexobject();
+ void errormessage2();
+ void usechurchhole();
+ void searchforfiles();
+ void monkspeaking();
+ void fadecalculation();
+ void waitframes();
+ void clearrest();
+ void getreelframeax();
+ void barwoman();
+ void roomname();
+ void credits();
+ void madmanrun();
+ void randomnum1();
+ void keeper();
+ void afternewroom();
+ void getexad();
+ void aide();
+ void openforsave();
+ void closefile();
+ void delcurs();
+ void randomaccess();
+ void calcfrframe();
+ void intromagic3();
+ void initialmoncols();
+ void checkforshake();
+ void usebuttona();
+ void cancelch1();
+ void getnextword();
+ void generalerror();
+ void actualload();
+ void allocateload();
+ void saveposition();
+ void mode640x480();
+ void openeden();
+ void execcommand();
+ void obsthatdothings();
+ void updatesymbolbot();
+ void findpuztext();
+ void usechurchgate();
+ void monkandryan();
+ void allocatebuffers();
+ void swapwithinv();
+ void usecontrol();
+ void buttonseven();
+ void redrawmainscrn();
+ void finishedwalking();
+ void findallryan();
+ void channel0tran();
+ void buttonpress();
+ void parseblaster();
+ void callhotellift();
+ void makemainscreen();
+ void intromonks2();
+ void usewinch();
+ void setbotright();
+ void readmouse3();
+ void showfirstuse();
+ void setupemm();
+ void usefullcart();
+ void transfertoex();
+ void getlocation();
+ void geteitherad();
+ void placesetobject();
+ void drawflags();
+ void zoomonoff();
+ void updatesymboltop();
+ void showryanpage();
+ void printlogo();
+ void allpointer();
+ void showseconduse();
+ void clearreels();
+ void malefan();
+ void dosaveload();
+ void createname();
+ void readcitypic();
+ void getpersontext();
+ void intoinv();
+ void showtime();
+ void parser();
+ void hangonw();
+ void intro();
+ void hangonp();
+ void fadescreendowns();
+ void showloadops();
+ void getridoftempsp();
+ void scanfornames();
+ void setallchanges();
+ void newgame();
+ void examinventory();
+ void standardload();
+ void undertextline();
+ void findroominloc();
+ void sitdowninbar();
+ void shownames();
+ void savefileread();
+ void emergencypurge();
+ void usemenu();
+ void alleybarksound();
+ void dosometalk();
+ void usecart();
+ void intromusic();
+ void makename();
+ void processtrigger();
+ void monmessage();
+ void readdesticon();
+ void randomnum2();
+ void loadsecondsample();
+ void transfercontoex();
+ void multiput();
+ void isitright();
+ void businessman();
+ void switchryanoff();
+ void commandwithob();
+ void panelicons1();
+ void adjustdown();
+ void withwhat();
+ void openob();
+ void createfile();
+ void userailing();
+ void accesslightoff();
+ void usehole();
+ void useobject();
+ void mainman();
+ void volumeadjust();
+ void checkiffree();
+};
+}
+
+#endif
diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp
new file mode 100644
index 0000000000..eebadfddae
--- /dev/null
+++ b/engines/dreamweb/dreamweb.cpp
@@ -0,0 +1,635 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://svn.scummvm.org:4444/svn/dreamweb/dreamweb.cpp $
+ * $Id: dreamweb.cpp 79 2011-06-05 08:26:54Z eriktorbjorn $
+ *
+ */
+
+#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"
+#include "common/timer.h"
+#include "common/util.h"
+
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+#include "graphics/palette.h"
+#include "graphics/surface.h"
+
+#include "dreamweb/dreamweb.h"
+#include "dreamweb/dreamgen.h"
+
+namespace DreamWeb {
+
+DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gameDesc) :
+ Engine(syst), _gameDescription(gameDesc), _rnd("dreamweb") {
+
+ _context.engine = this;
+ // Setup mixer
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+
+ _vSyncInterrupt = false;
+
+ _console = 0;
+ DebugMan.addDebugChannel(kDebugAnimation, "Animation", "Animation Debug Flag");
+ DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function");
+ _outSaveFile = 0;
+ _inSaveFile = 0;
+ _speed = 1;
+ _turbo = false;
+ _oldMouseState = 0;
+ _channel0 = 0;
+ _channel1 = 0;
+
+ _language = gameDesc->desc.language;
+}
+
+DreamWebEngine::~DreamWebEngine() {
+ DebugMan.clearAllDebugChannels();
+ delete _console;
+}
+
+static void vSyncInterrupt(void *refCon) {
+ DreamWebEngine *vm = (DreamWebEngine *)refCon;
+
+ if (!vm->isPaused()) {
+ vm->setVSyncInterrupt(true);
+ }
+}
+
+void DreamWebEngine::setVSyncInterrupt(bool flag) {
+ _vSyncInterrupt = flag;
+}
+
+void DreamWebEngine::waitForVSync() {
+ processEvents();
+
+ if (!_turbo) {
+ while (!_vSyncInterrupt) {
+ _system->delayMillis(10);
+ }
+ setVSyncInterrupt(false);
+ }
+
+ _context.doshake();
+ _context.dofade();
+ _system->updateScreen();
+}
+
+void DreamWebEngine::quit() {
+ _context.data.byte(DreamGen::DreamGenContext::kQuitrequested) = 1;
+ _context.data.byte(DreamGen::DreamGenContext::kLasthardkey) = 1;
+}
+
+void DreamWebEngine::processEvents() {
+ Common::EventManager *event_manager = _system->getEventManager();
+ if (event_manager->shouldQuit()) {
+ quit();
+ return;
+ }
+
+ if (_enableSavingOrLoading && _loadSavefile >= 0 && _loadSavefile <= 6) {
+ debug(1, "loading save state %d", _loadSavefile);
+ _context.data.byte(_context.kCurrentslot) = _loadSavefile;
+ _loadSavefile = -1;
+ _context.loadposition();
+ _context.data.byte(_context.kGetback) = 1;
+ }
+
+ soundHandler();
+ Common::Event event;
+ int softKey, hardKey;
+ while (event_manager->pollEvent(event)) {
+ switch(event.type) {
+ case Common::EVENT_RTL:
+ quit();
+ break;
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ switch (event.kbd.keycode) {
+
+ case Common::KEYCODE_d:
+ _console->attach();
+ _console->onFrame();
+ break;
+
+ case Common::KEYCODE_f:
+ setSpeed(_speed != 20? 20: 1);
+ break;
+
+ case Common::KEYCODE_g:
+ _turbo = !_turbo;
+ break;
+
+ case Common::KEYCODE_c: //skip statue puzzle
+ _context.data.byte(DreamGen::DreamGenContext::kSymbolbotnum) = 3;
+ _context.data.byte(DreamGen::DreamGenContext::kSymboltopnum) = 5;
+ break;
+
+ default:
+ break;
+ }
+
+ return; //do not pass ctrl + key to the engine
+ }
+
+ // Some parts of the ASM code uses the hardware key
+ // code directly. We don't have that code, so we fake
+ // it for the keys where it's needed and assume it's
+ // 0 (which is actually an invalid value, as far as I
+ // know) otherwise.
+
+ hardKey = 0;
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_ESCAPE:
+ hardKey = 1;
+ break;
+ case Common::KEYCODE_SPACE:
+ hardKey = 57;
+ break;
+ default:
+ hardKey = 0;
+ break;
+ }
+
+ _context.data.byte(DreamGen::DreamGenContext::kLasthardkey) = hardKey;
+
+ // The rest of the keys are converted to ASCII. This
+ // is fairly restrictive, and eventually we may want
+ // to let through more keys. I think this is mostly to
+ // keep weird glyphs out of savegame names.
+
+ softKey = 0;
+
+ if (event.kbd.keycode >= Common::KEYCODE_a && event.kbd.keycode <= Common::KEYCODE_z) {
+ softKey = event.kbd.ascii & ~0x20;
+ } else if (event.kbd.keycode == Common::KEYCODE_MINUS ||
+ event.kbd.keycode == Common::KEYCODE_SPACE ||
+ (event.kbd.keycode >= Common::KEYCODE_0 && event.kbd.keycode <= Common::KEYCODE_9)) {
+ softKey = event.kbd.ascii;
+ } else if (event.kbd.keycode >= Common::KEYCODE_KP0 && event.kbd.keycode <= Common::KEYCODE_KP9) {
+ softKey = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
+ } else if (event.kbd.keycode == Common::KEYCODE_KP_MINUS) {
+ softKey = '-';
+ } else if (event.kbd.keycode == Common::KEYCODE_BACKSPACE ||
+ event.kbd.keycode == Common::KEYCODE_DELETE) {
+ softKey = 8;
+ } else if (event.kbd.keycode == Common::KEYCODE_RETURN
+ || event.kbd.keycode == Common::KEYCODE_KP_ENTER) {
+ softKey = 13;
+ }
+
+ if (softKey)
+ keyPressed(softKey);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+Common::Error DreamWebEngine::run() {
+ syncSoundSettings();
+ _console = new DreamWebConsole(this);
+
+ _loadSavefile = Common::ConfigManager::instance().getInt("save_slot");
+
+ getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70, this);
+ _context.__start();
+ _context.data.byte(DreamGen::DreamGenContext::kQuitrequested) = 0;
+
+ getTimerManager()->removeTimerProc(vSyncInterrupt);
+
+ return Common::kNoError;
+}
+
+void DreamWebEngine::setSpeed(uint speed) {
+ debug(0, "setting speed %u", speed);
+ _speed = speed;
+ getTimerManager()->removeTimerProc(vSyncInterrupt);
+ getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70 / speed, this);
+}
+
+void DreamWebEngine::openFile(const Common::String &name) {
+ processEvents();
+ closeFile();
+ if (_file.open(name))
+ return;
+ _inSaveFile = _system->getSavefileManager()->openForLoading(name);
+ if (_inSaveFile)
+ return;
+ error("cannot open file %s", name.c_str());
+}
+
+uint32 DreamWebEngine::skipBytes(uint32 bytes) {
+ if (!_file.seek(bytes, SEEK_CUR))
+ error("seek failed");
+ return _file.pos();
+}
+
+uint32 DreamWebEngine::readFromFile(uint8 *dst, unsigned size) {
+ processEvents();
+ if (_file.isOpen())
+ return _file.read(dst, size);
+ if (_inSaveFile)
+ return _inSaveFile->read(dst, size);
+ error("file was not opened (read before open)");
+}
+
+void DreamWebEngine::closeFile() {
+ processEvents();
+ if (_file.isOpen())
+ _file.close();
+ delete _inSaveFile;
+ _inSaveFile = 0;
+ delete _outSaveFile;
+ _outSaveFile = 0;
+}
+
+void DreamWebEngine::openSaveFileForWriting(const Common::String &name) {
+ processEvents();
+ delete _outSaveFile;
+ _outSaveFile = _system->getSavefileManager()->openForSaving(name);
+}
+
+bool DreamWebEngine::openSaveFileForReading(const Common::String &name) {
+ processEvents();
+ delete _inSaveFile;
+ _inSaveFile = _system->getSavefileManager()->openForLoading(name);
+ return _inSaveFile != 0;
+}
+
+uint DreamWebEngine::writeToSaveFile(const uint8 *data, uint size) {
+ processEvents();
+ if (!_outSaveFile)
+ error("save file was not opened for writing");
+ return _outSaveFile->write(data, size);
+}
+
+uint DreamWebEngine::readFromSaveFile(uint8 *data, uint size) {
+ processEvents();
+ if (!_inSaveFile)
+ error("save file was not opened for reading");
+ return _inSaveFile->read(data, size);
+}
+
+
+void DreamWebEngine::keyPressed(uint16 ascii) {
+ debug(2, "key pressed = %04x", ascii);
+ uint8* keybuf = _context.data.ptr(5912, 16); //fixme: some hardcoded offsets are not added as consts
+ uint16 in = (_context.data.word(DreamGen::DreamGenContext::kBufferin) + 1) & 0x0f;
+ uint16 out = _context.data.word(DreamGen::DreamGenContext::kBufferout);
+ if (in == out) {
+ warning("keyboard buffer is full");
+ return;
+ }
+ _context.data.word(DreamGen::DreamGenContext::kBufferin) = in;
+ keybuf[in] = ascii;
+}
+
+void DreamWebEngine::mouseCall() {
+ processEvents();
+ Common::EventManager *eventMan = _system->getEventManager();
+ Common::Point pos = eventMan->getMousePos();
+ if (pos.x > 298)
+ pos.x = 298;
+ if (pos.x < 15)
+ pos.x = 15;
+ if (pos.y < 15)
+ pos.y = 15;
+ if (pos.y > 184)
+ pos.y = 184;
+ _context.cx = pos.x;
+ _context.dx = pos.y;
+
+ unsigned state = eventMan->getButtonState();
+ _context.bx = state == _oldMouseState? 0: state;
+ _oldMouseState = state;
+ _context.flags._c = false;
+}
+
+void DreamWebEngine::fadeDos() {
+ _context.ds = _context.es = _context.data.word(DreamGen::DreamGenContext::kBuffers);
+ return; //fixme later
+ waitForVSync();
+ //processEvents will be called from vsync
+ uint8 *dst = _context.es.ptr(DreamGen::DreamGenContext::kStartpal, 768);
+ getPalette(dst, 0, 64);
+ for(int fade = 0; fade < 64; ++fade) {
+ for(int c = 0; c < 768; ++c) { //original sources decrement 768 values -> 256 colors
+ if (dst[c]) {
+ --dst[c];
+ }
+ }
+ setPalette(dst, 0, 64);
+ waitForVSync();
+ }
+}
+
+void DreamWebEngine::setPalette() {
+ processEvents();
+ unsigned n = (uint16)_context.cx;
+ uint8 *src = _context.ds.ptr(_context.si, n * 3);
+ setPalette(src, _context.al, n);
+ _context.si += n * 3;
+ _context.cx = 0;
+}
+
+void DreamWebEngine::getPalette(uint8 *data, uint start, uint count) {
+ _system->getPaletteManager()->grabPalette(data, start, count);
+ while(count--)
+ *data++ >>= 2;
+}
+
+void DreamWebEngine::setPalette(const uint8 *data, uint start, uint count) {
+ assert(start + count <= 256);
+ uint8 fixed[768];
+ for(uint i = 0; i < count * 3; ++i) {
+ fixed[i] = data[i] << 2;
+ }
+ _system->getPaletteManager()->setPalette(fixed, start, count);
+}
+
+
+void DreamWebEngine::blit(const uint8 *src, int pitch, int x, int y, int w, int h) {
+ if (y + h > 200)
+ h = 200 - y;
+ if (x + w > 320)
+ w = 320 - x;
+ if (h <= 0 || w <= 0)
+ return;
+ _system->copyRectToScreen(src, pitch, x, y, w, h);
+}
+
+void DreamWebEngine::printUnderMonitor() {
+ _context.es = _context.data.word(DreamGen::DreamGenContext::kWorkspace);
+ _context.di = DreamGen::DreamGenContext::kScreenwidth * 43 + 76;
+ _context.si = _context.di + 8 * DreamGen::DreamGenContext::kScreenwidth;
+
+ Graphics::Surface *s = _system->lockScreen();
+ if (!s)
+ error("lockScreen failed");
+
+ for(uint y = 0; y < 104; ++y) {
+ uint8 *src = (uint8 *)s->getBasePtr(76, 43 + 8 + y);
+ uint8 *dst = _context.es.ptr(_context.di, 170);
+ for(uint x = 0; x < 170; ++x) {
+ if (*src < 231)
+ *dst++ = *src++;
+ else {
+ ++dst; ++src;
+ }
+ }
+ _context._add(_context.di, DreamGen::DreamGenContext::kScreenwidth);
+ _context._add(_context.si, DreamGen::DreamGenContext::kScreenwidth);
+ }
+ _context.cx = 0;
+ _system->unlockScreen();
+}
+
+void DreamWebEngine::cls() {
+ _system->fillScreen(0);
+}
+
+void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) {
+ debug(1, "playSound(%u, %u, %u)", channel, id, loops);
+
+ int bank = 0;
+ bool speech = false;
+ Audio::Mixer::SoundType type = channel == 0?
+ Audio::Mixer::kMusicSoundType: Audio::Mixer::kSFXSoundType;
+
+ if (id >= 12) {
+ id -= 12;
+ bank = 1;
+ if (id == 50) {
+ speech = true;
+ type = Audio::Mixer::kSpeechSoundType;
+ }
+ }
+ const SoundData &data = _soundData[bank];
+
+ Audio::SeekableAudioStream *raw;
+ if (!speech) {
+ if (id >= data.samples.size() || data.samples[id].size == 0) {
+ warning("invalid sample #%u played", id);
+ return;
+ }
+
+ const Sample &sample = data.samples[id];
+ uint8 *buffer = (uint8 *)malloc(sample.size);
+ if (!buffer)
+ error("out of memory: cannot allocate memory for sound(%u bytes)", sample.size);
+ memcpy(buffer, data.data.begin() + sample.offset, sample.size);
+
+ raw = Audio::makeRawStream(
+ buffer,
+ sample.size, 22050, Audio::FLAG_UNSIGNED);
+ } else {
+ uint8 *buffer = (uint8 *)malloc(_speechData.size());
+ memcpy(buffer, _speechData.begin(), _speechData.size());
+ if (!buffer)
+ error("out of memory: cannot allocate memory for sound(%u bytes)", _speechData.size());
+ raw = Audio::makeRawStream(
+ buffer,
+ _speechData.size(), 22050, Audio::FLAG_UNSIGNED);
+
+ }
+
+ Audio::AudioStream *stream;
+ if (loops > 1) {
+ stream = new Audio::LoopingAudioStream(raw, loops < 255? loops: 0);
+ } else
+ stream = raw;
+
+ if (_mixer->isSoundHandleActive(_channelHandle[channel]))
+ _mixer->stopHandle(_channelHandle[channel]);
+ _mixer->playStream(type, &_channelHandle[channel], stream);
+}
+
+bool DreamWebEngine::loadSpeech(const Common::String &filename) {
+ if (ConfMan.getBool("speech_mute"))
+ return false;
+
+ Common::File file;
+ if (!file.open("speech/" + filename))
+ return false;
+
+ debug(1, "loadSpeech(%s)", filename.c_str());
+
+ uint size = file.size();
+ _speechData.resize(size);
+ file.read(_speechData.begin(), size);
+ file.close();
+ return true;
+}
+
+
+void DreamWebEngine::soundHandler() {
+ _context.data.byte(_context.kSubtitles) = ConfMan.getBool("subtitles");
+ _context.push(_context.ax);
+ _context.volumeadjust();
+ _context.ax = _context.pop();
+
+ uint volume = _context.data.byte(DreamGen::DreamGenContext::kVolume);
+ //.vol file loaded into soundbuf:0x4000
+ //volume table at (volume * 0x100 + 0x3f00)
+ //volume value could be from 1 to 7
+ //1 - 0x10-0xff
+ //2 - 0x1f-0xdf
+ //3 - 0x2f-0xd0
+ //4 - 0x3e-0xc1
+ //5 - 0x4d-0xb2
+ //6 - 0x5d-0xa2
+ //7 - 0x6f-0x91
+ if (volume >= 8)
+ volume = 7;
+ volume = (8 - volume) * Audio::Mixer::kMaxChannelVolume / 8;
+ _mixer->setChannelVolume(_channelHandle[0], volume);
+
+ uint8 ch0 = _context.data.byte(DreamGen::DreamGenContext::kCh0playing);
+ if (ch0 == 255)
+ ch0 = 0;
+ uint8 ch1 = _context.data.byte(DreamGen::DreamGenContext::kCh1playing);
+ if (ch1 == 255)
+ ch1 = 0;
+ uint8 ch0loop = _context.data.byte(DreamGen::DreamGenContext::kCh0repeat);
+
+ if (_channel0 != ch0) {
+ _channel0 = ch0;
+ if (ch0) {
+ playSound(0, ch0, ch0loop);
+ }
+ }
+ if (_channel1 != ch1) {
+ _channel1 = ch1;
+ if (ch1) {
+ playSound(1, ch1, 1);
+ }
+ }
+ if (!_mixer->isSoundHandleActive(_channelHandle[0])) {
+ _context.data.byte(DreamGen::DreamGenContext::kCh0playing) = 255;
+ _channel0 = 0;
+ }
+ if (!_mixer->isSoundHandleActive(_channelHandle[1])) {
+ _context.data.byte(DreamGen::DreamGenContext::kCh1playing) = 255;
+ _channel1 = 0;
+ }
+
+}
+
+void DreamWebEngine::loadSounds(uint bank, const Common::String &filename) {
+ debug(1, "loadSounds(%u, %s)", bank, filename.c_str());
+ Common::File file;
+ if (!file.open(filename)) {
+ warning("cannot open %s", filename.c_str());
+ return;
+ }
+
+ uint8 header[0x60];
+ file.read(header, sizeof(header));
+ uint tablesize = READ_LE_UINT16(header + 0x32);
+ debug(1, "table size = %u", tablesize);
+
+ SoundData &soundData = _soundData[bank];
+ soundData.samples.resize(tablesize / 6);
+ uint total = 0;
+ for(uint i = 0; i < tablesize / 6; ++i) {
+ uint8 entry[6];
+ Sample &sample = soundData.samples[i];
+ file.read(entry, sizeof(entry));
+ sample.offset = entry[0] * 0x4000 + READ_LE_UINT16(entry + 1);
+ sample.size = READ_LE_UINT16(entry + 3) * 0x800;
+ total += sample.size;
+ debug(1, "offset: %08x, size: %u", sample.offset, sample.size);
+ }
+ soundData.data.resize(total);
+ file.read(soundData.data.begin(), total);
+ file.close();
+}
+
+uint8 DreamWebEngine::modifyChar(uint8 c) const {
+ if (c < 128)
+ return c;
+
+ switch(_language) {
+ case Common::DE_DEU:
+ switch(c)
+ {
+ case 129:
+ return 'Z' + 3;
+ case 132:
+ return 'Z' + 1;
+ case 142:
+ return 'Z' + 4;
+ case 154:
+ return 'Z' + 6;
+ case 255:
+ return 'A' - 1;
+ case 153:
+ return 'Z' + 5;
+ case 148:
+ return 'Z' + 2;
+ default:
+ return c;
+ }
+ case Common::ES_ESP:
+ switch(c) {
+ case 160:
+ return 'Z' + 1;
+ case 130:
+ return 'Z' + 2;
+ case 161:
+ return 'Z' + 3;
+ case 162:
+ return 'Z' + 4;
+ case 163:
+ return 'Z' + 5;
+ case 164:
+ return 'Z' + 6;
+ case 165:
+ return ',' - 1;
+ case 168:
+ return 'A' - 1;
+ case 173:
+ return 'A' - 4;
+ case 129:
+ return 'A' - 5;
+ default:
+ return c;
+ }
+ default:
+ return c;
+ }
+}
+
+} // End of namespace DreamWeb
+
+
diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h
new file mode 100644
index 0000000000..7323cfe836
--- /dev/null
+++ b/engines/dreamweb/dreamweb.h
@@ -0,0 +1,158 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://svn.scummvm.org:4444/svn/dreamweb/dreamweb.h $
+ * $Id: dreamweb.h 77 2011-05-18 14:26:43Z digitall $
+ *
+ */
+
+#ifndef DREAMWEB_H
+#define DREAMWEB_H
+
+#include "common/error.h"
+#include "common/file.h"
+#include "common/random.h"
+#include "common/rect.h"
+#include "common/savefile.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+
+#include "engines/advancedDetector.h"
+#include "engines/engine.h"
+
+#include "dreamweb/dreamgen.h"
+#include "dreamweb/console.h"
+
+namespace DreamWeb {
+
+// Engine Debug Flags
+enum {
+ kDebugAnimation = (1 << 0),
+ kDebugSaveLoad = (1 << 1)
+};
+
+struct DreamWebGameDescription {
+ ADGameDescription desc;
+};
+
+class DreamWebEngine : public Engine {
+private:
+ DreamWebConsole *_console;
+ bool _vSyncInterrupt;
+
+protected:
+ // Engine APIs
+ virtual Common::Error run();
+ virtual bool hasFeature(EngineFeature f) const;
+
+public:
+ DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gameDesc);
+ virtual ~DreamWebEngine();
+
+ void setVSyncInterrupt(bool flag);
+ void waitForVSync();
+
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const Common::String &desc);
+
+ bool canLoadGameStateCurrently();
+ bool canSaveGameStateCurrently();
+
+ uint8 randomNumber() { return _rnd.getRandomNumber(255); }
+
+ void openFile(const Common::String &name);
+ uint32 readFromFile(uint8 *data, unsigned size);
+ uint32 skipBytes(uint32 bytes);
+ void closeFile();
+
+ void mouseCall(); //fill mouse pos and button state
+ void processEvents();
+ void setPalette();
+ void fadeDos();
+ void blit(const uint8 *src, int pitch, int x, int y, int w, int h);
+ void cls();
+
+ void getPalette(uint8 *data, uint start, uint count);
+ void setPalette(const uint8 *data, uint start, uint count);
+
+ void openSaveFileForWriting(const Common::String &name);
+ uint writeToSaveFile(const uint8 *data, uint size);
+
+ bool openSaveFileForReading(const Common::String &name);
+ uint readFromSaveFile(uint8 *data, uint size);
+
+ void setShakePos(int pos) { _system->setShakePos(pos); }
+ void printUnderMonitor();
+
+ void quit();
+
+ void loadSounds(uint bank, const Common::String &file);
+ bool loadSpeech(const Common::String &filename);
+
+ void enableSavingOrLoading(bool enable = true) { _enableSavingOrLoading = enable; }
+
+ Common::Language getLanguage() const { return _language; }
+ uint8 modifyChar(uint8 c) const;
+
+private:
+ void keyPressed(uint16 ascii);
+ void setSpeed(uint speed);
+ void soundHandler();
+ void playSound(uint8 channel, uint8 id, uint8 loops);
+
+ const DreamWebGameDescription *_gameDescription;
+ Common::RandomSource _rnd;
+
+ Common::File _file;
+ Common::OutSaveFile *_outSaveFile;
+ Common::InSaveFile *_inSaveFile;
+
+ uint _speed;
+ bool _turbo;
+ uint _oldMouseState;
+ int _loadSavefile;
+ bool _enableSavingOrLoading;
+ Common::Language _language;
+
+ struct Sample {
+ uint offset;
+ uint size;
+ Sample(): offset(), size() {}
+ };
+
+ struct SoundData {
+ Common::Array<Sample> samples;
+ Common::Array<uint8> data;
+ };
+ SoundData _soundData[2];
+ Common::Array<uint8> _speechData;
+
+ Audio::SoundHandle _channelHandle[2];
+ uint8 _channel0, _channel1;
+
+ DreamGen::DreamGenContext _context;
+};
+
+} // End of namespace DreamWeb
+
+#endif
diff --git a/engines/dreamweb/module.mk b/engines/dreamweb/module.mk
new file mode 100644
index 0000000000..3b0c7f3325
--- /dev/null
+++ b/engines/dreamweb/module.mk
@@ -0,0 +1,16 @@
+MODULE := engines/dreamweb
+
+MODULE_OBJS := \
+ console.o \
+ detection.o \
+ dreamweb.o \
+ dreamgen.o \
+ stubs.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_DREAMWEB), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/dreamweb/runtime.h b/engines/dreamweb/runtime.h
new file mode 100644
index 0000000000..a97ea2cf3d
--- /dev/null
+++ b/engines/dreamweb/runtime.h
@@ -0,0 +1,561 @@
+#ifndef ENGINES_DREAMGEN_RUNTIME_H__
+#define ENGINES_DREAMGEN_RUNTIME_H__
+
+#include <assert.h>
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/debug.h"
+#include "common/hashmap.h"
+#include "common/list.h"
+#include "common/ptr.h"
+
+namespace DreamWeb {
+ class DreamWebEngine;
+}
+
+namespace DreamGen {
+
+//fixme: name clash
+#undef random
+
+struct Register {
+ union {
+ uint16 _value;
+ uint8 _part[2];
+ };
+ inline Register(): _value() {}
+ inline Register& operator=(uint16 v) { _value = v; return *this; }
+ inline operator uint16&() { return _value; }
+ inline void cbw() {
+ if (_value & 0x80)
+ _value |= 0xff00;
+ else
+ _value &= 0x7f;
+ }
+};
+
+template<int kIndex> //from low to high
+struct RegisterPart {
+ uint8 &_value;
+
+ explicit inline RegisterPart(Register &reg) : _value(reg._part[kIndex]) {}
+
+ inline operator uint8&() {
+ return _value;
+ }
+
+ inline RegisterPart& operator=(const RegisterPart& o) {
+ _value = o._value;
+ return *this;
+ }
+
+ inline RegisterPart& operator=(uint8 v) {
+ _value = v;
+ return *this;
+ }
+};
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ typedef RegisterPart<0> LowPartOfRegister;
+ typedef RegisterPart<1> HighPartOfRegister;
+#else
+ typedef RegisterPart<1> LowPartOfRegister;
+ typedef RegisterPart<0> HighPartOfRegister;
+#endif
+
+class WordRef {
+ uint8 *_data;
+ unsigned _index;
+ uint16 _value;
+
+public:
+ inline WordRef(Common::Array<uint8> &data, unsigned index) : _data(data.begin() + index), _index(index) {
+ assert(index + 1 < data.size());
+ _value = _data[0] | (_data[1] << 8);
+ }
+
+ inline WordRef& operator=(const WordRef &ref) {
+ _value = ref._value;
+ return *this;
+ }
+
+ inline WordRef& operator=(uint16 v) {
+ _value = v;
+ return *this;
+ }
+
+ inline operator uint16&() {
+ return _value;
+ }
+
+ inline ~WordRef() {
+ _data[0] = _value & 0xff;
+ _data[1] = _value >> 8;
+ _value = _data[0] | (_data[1] << 8);
+ }
+};
+
+struct Segment {
+ Common::Array<uint8> data;
+
+ inline void assign(const uint8 *b, const uint8 *e) {
+ data.assign(b, e);
+ }
+
+ inline uint8 &byte(unsigned index) {
+ assert(index < data.size());
+ return data[index];
+ }
+
+ inline WordRef word(unsigned index) {
+ return WordRef(data, index);
+ }
+
+ inline uint8* ptr(unsigned index, unsigned size) {
+ assert(index + size <= data.size());
+ return data.begin() + index;
+ }
+};
+
+typedef Common::SharedPtr<Segment> SegmentPtr;
+
+class Context;
+
+class SegmentRef {
+ Context *_context;
+ uint16 _value;
+ SegmentPtr _segment;
+
+public:
+ SegmentRef(Context *ctx, uint16 value = 0, SegmentPtr segment = SegmentPtr()): _context(ctx), _value(value), _segment(segment) {
+ }
+
+ inline void reset(uint16 value);
+
+ inline SegmentRef& operator=(const uint16 id) {
+ reset(id);
+ return *this;
+ }
+
+ inline SegmentRef& operator=(const SegmentRef &ref) {
+ _context = ref._context;
+ _value = ref._value;
+ _segment = ref._segment;
+ return *this;
+ }
+
+ inline uint8 &byte(unsigned index) {
+ assert(_segment != 0);
+ return _segment->byte(index);
+ }
+
+ inline operator uint16() const {
+ return _value;
+ }
+
+ inline WordRef word(unsigned index) {
+ //debug(1, "getting word ref for %04x:%d", _value, index);
+ assert(_segment != 0);
+ return _segment->word(index);
+ }
+
+ inline void assign(const uint8 *b, const uint8 *e) {
+ assert(_segment != 0);
+ _segment->assign(b, e);
+ }
+
+ inline uint8* ptr(unsigned index, unsigned size) {
+ assert(_segment != 0);
+ return _segment->ptr(index, size);
+ }
+};
+
+struct Flags {
+ bool _z, _c, _s, _o;
+ inline Flags(): _z(true), _c(false), _s(false), _o(false) {}
+
+ inline bool z() const { return _z; }
+ inline bool c() const { return _c; }
+ inline bool s() const { return _s; }
+
+ inline bool l() const { return _o != _s; }
+ inline bool le() const { return _o != _s|| _z; }
+
+ inline void update_zs(uint8 v) {
+ _s = v & 0x80;
+ _z = v == 0;
+ }
+
+ inline void update_zs(uint16 v) {
+ _s = v & 0x8000;
+ _z = v == 0;
+ }
+
+ inline void update_o(uint8 v, uint8 a, uint8 b) {
+ uint8 s1 = a & 0x80, s2 = b & 0x80;
+ _o = (s1 == s2) && (v & 0x80) != s1;
+ }
+
+ inline void update_o(uint16 v, uint16 a, uint16 b) {
+ uint16 s1 = a & 0x8000, s2 = b & 0x8000;
+ _o = (s1 == s2) && (v & 0x8000) != s1;
+ }
+};
+
+class Context {
+ typedef Common::HashMap<uint16, SegmentPtr> SegmentMap;
+ SegmentMap _segments;
+
+ typedef Common::List<uint16> FreeSegmentList;
+ FreeSegmentList _freeSegments;
+
+public:
+ DreamWeb::DreamWebEngine *engine;
+
+ enum { kDefaultDataSegment = 0x1000 };
+
+ Register ax, dx, bx, cx, si, di;
+ LowPartOfRegister al;
+ HighPartOfRegister ah;
+ LowPartOfRegister bl;
+ HighPartOfRegister bh;
+ LowPartOfRegister cl;
+ HighPartOfRegister ch;
+ LowPartOfRegister dl;
+ HighPartOfRegister dh;
+
+ SegmentRef cs, ds, es, data;
+ //data == fake segment register always pointing to data segment
+ Flags flags;
+
+ inline Context(): engine(0), al(ax), ah(ax), bl(bx), bh(bx), cl(cx), ch(cx), dl(dx), dh(dx),
+ cs(this), ds(this), es(this), data(this) {
+ _segments[kDefaultDataSegment] = SegmentPtr(new Segment());
+ cs.reset(kDefaultDataSegment);
+ ds.reset(kDefaultDataSegment);
+ es.reset(kDefaultDataSegment);
+ data.reset(kDefaultDataSegment);
+ }
+
+ SegmentRef getSegment(uint16 value) {
+ SegmentMap::iterator i = _segments.find(value);
+ assert(i != _segments.end());
+ return SegmentRef(this, value, i->_value);
+ }
+
+ SegmentRef allocateSegment(uint size) {
+ unsigned id;
+ if (_freeSegments.empty())
+ id = kDefaultDataSegment + _segments.size();
+ else {
+ id = _freeSegments.front();
+ _freeSegments.pop_front();
+ }
+ assert(!_segments.contains(id));
+ SegmentPtr seg(new Segment());
+ seg->data.resize(size);
+ _segments[id] = seg;
+ return SegmentRef(this, id, seg);
+ }
+
+ void deallocateSegment(uint16 id) {
+ SegmentMap::iterator i = _segments.find(id);
+ assert(i != _segments.end());
+ _segments.erase(i);
+ _freeSegments.push_back(id);
+ }
+
+ inline void _cmp(uint8 a, uint8 b) {
+ _sub(a, b);
+ }
+
+ inline void _cmp(uint16 a, uint16 b) {
+ _sub(a, b);
+ }
+
+ inline void _test(uint8 a, uint8 b) {
+ _and(a, b);
+ }
+
+ inline void _test(uint16 a, uint16 b) {
+ _and(a, b);
+ }
+
+ inline void _add(uint8 &dst, uint8 src) {
+ unsigned r = (unsigned)dst + src;
+ flags.update_o((uint8)r, dst, src);
+ flags._c = r >= 0x100;
+ dst = r;
+ flags.update_zs(dst);
+ }
+
+ inline void _add(uint16 &dst, uint16 src) {
+ unsigned r = (unsigned)dst + src;
+ flags.update_o((uint16)r, dst, src);
+ flags._c = r >= 0x10000;
+ dst = r;
+ flags.update_zs(dst);
+ }
+
+ inline void _sub(uint8 &dst, uint8 src) {
+ flags.update_o(uint8(dst - src), dst, (uint8)-src);
+ flags._c = dst < src;
+ dst -= src;
+ flags.update_zs(dst);
+ }
+
+ inline void _sub(uint16 &dst, uint16 src) {
+ flags.update_o(uint16(dst - src), dst, (uint16)-src);
+ flags._c = dst < src;
+ dst -= src;
+ flags.update_zs(dst);
+ }
+
+ inline void _inc(uint8 &dst) {
+ flags.update_o((uint8)(dst + 1), dst, 1);
+ ++dst;
+ flags.update_zs(dst);
+ }
+
+ inline void _inc(uint16 &dst) {
+ flags.update_o((uint16)(dst + 1), dst, 1);
+ ++dst;
+ flags.update_zs(dst);
+ }
+
+ inline void _dec(uint8 &dst) {
+ flags.update_o(uint8(dst - 1), dst, 1);
+ --dst;
+ flags.update_zs(dst);
+ }
+
+ inline void _dec(uint16 &dst) {
+ flags.update_o(uint16(dst - 1), dst, 1);
+ --dst;
+ flags.update_zs(dst);
+ }
+
+ inline void _and(uint8 &dst, uint8 src) {
+ dst &= src;
+ flags.update_zs(dst);
+ flags._c = flags._o = false;
+ }
+
+ inline void _and(uint16 &dst, uint16 src) {
+ dst &= src;
+ flags.update_zs(dst);
+ flags._c = flags._o = false;
+ }
+
+ inline void _or(uint8 &dst, uint8 src) {
+ dst |= src;
+ flags.update_zs(dst);
+ flags._c = flags._o = false;
+ }
+
+ inline void _or(uint16 &dst, uint16 src) {
+ dst |= src;
+ flags.update_zs(dst);
+ flags._c = flags._o = false;
+ }
+
+ inline void _xor(uint8 &dst, uint8 src) {
+ dst ^= src;
+ flags.update_zs(dst);
+ flags._c = flags._o = false;
+ }
+
+ inline void _xor(uint16 &dst, uint16 src) {
+ dst ^= src;
+ flags.update_zs(dst);
+ flags._c = flags._o = false;
+ }
+
+ inline void _shr(uint8 &dst, uint8 src) {
+ src &= 0x1f;
+ if (src > 0) {
+ dst >>= (src - 1);
+ flags._c = dst & 1;
+ dst >>= 1;
+ flags.update_zs(dst);
+ }
+ if (src == 1)
+ flags._o = dst & 0x80;
+ }
+
+ inline void _shr(uint16 &dst, uint8 src) {
+ src &= 0x1f;
+ if (src > 0) {
+ dst >>= (src - 1);
+ flags._c = dst & 1;
+ dst >>= 1;
+ flags.update_zs(dst);
+ }
+ if (src == 1)
+ flags._o = dst & 0x8000;
+ }
+
+ inline void _shl(uint8 &dst, uint8 src) {
+ src &= 0x1f;
+ if (src > 0) {
+ dst <<= (src - 1);
+ flags._c = dst & 0x80;
+ dst <<= 1;
+ flags.update_zs(dst);
+ }
+ if (src == 1)
+ flags._o = ((dst & 0x80) != 0) == flags._c;
+ }
+ inline void _shl(uint16 &dst, uint8 src) {
+ src &= 0x1f;
+ if (src > 0) {
+ dst <<= (src - 1);
+ flags._c = dst & 0x8000;
+ dst <<= 1;
+ flags.update_zs(dst);
+ }
+ if (src == 1)
+ flags._o = ((dst & 0x8000) != 0) == flags._c;
+ }
+
+ inline void _mul(uint8 src) {
+ unsigned r = unsigned(al) * src;
+ ax = (uint16)r;
+ flags._c = r >= 0x10000;
+ flags._z = r == 0;
+ flags._s = r & 0x8000;
+ flags._o = ah != 0;
+ }
+
+ inline void _mul(uint16 src) {
+ unsigned r = unsigned(ax) * src; //assuming here that we have at least 32 bits
+ dx = (r >> 16) & 0xffff;
+ ax = r & 0xffff;
+ flags._c = false;
+ flags._z = r == 0;
+ flags._s = r & 0x80000000;
+ flags._o = dx != 0;
+ }
+
+ inline void _neg(uint8 &src) {
+ uint8 r = 0;
+ _sub(r, src);
+ src = r;
+ }
+
+ inline void _neg(uint16 &src) {
+ uint16 r = 0;
+ _sub(r, src);
+ src = r;
+ }
+
+ inline void _lodsb() {
+ al = ds.byte(si++);
+ }
+
+ inline void _lodsw() {
+ ax = ds.word(si);
+ si += 2;
+ }
+
+ inline void _movsb() {
+ es.byte(di++) = ds.byte(si++);
+ }
+
+ inline void _movsb(uint size, bool clear_cx = false) {
+ assert(size != 0xffff);
+ //fixme: add overlap and segment boundary check and rewrite
+ while(size--)
+ _movsb();
+ if (clear_cx)
+ cx = 0;
+ }
+
+ inline void _movsw() {
+ _movsb();
+ _movsb();
+ }
+
+ inline void _movsw(uint size, bool clear_cx = false) {
+ assert(size != 0xffff);
+ _movsb(size * 2, clear_cx);
+ }
+
+ inline void _stosb() {
+ es.byte(di++) = al;
+ }
+
+ inline void _stosb(uint size, bool clear_cx = false) {
+ assert(size != 0xffff);
+ uint8 *dst = es.ptr(di, size);
+ memset(dst, al, size);
+ di += size;
+ if (clear_cx)
+ cx = 0;
+ }
+
+ inline void _stosw() {
+ es.byte(di++) = al;
+ es.byte(di++) = ah;
+ }
+
+ inline void _stosw(uint size, bool clear_cx = false) {
+ assert(size != 0xffff);
+ uint8 *dst = es.ptr(di, size * 2);
+ di += 2 * size;
+ while(size--) {
+ *dst++ = al;
+ *dst++ = ah;
+ }
+ if (clear_cx)
+ cx = 0;
+ }
+
+ inline void _xchg(uint16 &a, uint16 &b) {
+ uint16 x = a;
+ a = b;
+ b = x;
+ }
+
+ inline void _xchg(uint8 &a, uint8 &b) {
+ uint8 t = a;
+ a = b;
+ b = t;
+ }
+
+ Common::Array<uint16> stack;
+ inline void push(uint16 v) {
+ stack.push_back(v);
+ }
+
+ inline uint16 pop() {
+ assert(!stack.empty());
+ uint16 v = stack.back();
+ stack.pop_back();
+ return v;
+ }
+};
+
+inline void SegmentRef::reset(uint16 value) {
+ *this = _context->getSegment(value);
+}
+
+class StackChecker {
+ const Context &_context;
+ const uint _stackDepth;
+
+public:
+ StackChecker(const Context &context): _context(context), _stackDepth(context.stack.size()) {}
+ ~StackChecker() { assert(_context.stack.size() == _stackDepth); }
+};
+
+#ifndef NDEBUG
+# define STACK_CHECK StackChecker checker(*this)
+#else
+# define STACK_CHECK do {} while (0)
+#endif
+
+}
+
+#endif
+
diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp
new file mode 100644
index 0000000000..5614aa391a
--- /dev/null
+++ b/engines/dreamweb/stubs.cpp
@@ -0,0 +1,557 @@
+#include "dreamweb/dreamweb.h"
+#include "engines/util.h"
+#include "graphics/surface.h"
+
+namespace DreamGen {
+
+Common::String getFilename(Context &context) {
+ uint16 name_ptr = context.dx;
+ Common::String name;
+ uint8 c;
+ while((c = context.cs.byte(name_ptr++)) != 0)
+ name += (char)c;
+ return name;
+}
+
+void DreamGenContext::multiget() {
+ unsigned w = (uint8)cl, h = (uint8)ch;
+ unsigned x = (uint16)di, y = (uint16)bx;
+ unsigned src = x + y * kScreenwidth;
+ unsigned dst = (uint16)si;
+ es = ds;
+ ds = data.word(kWorkspace);
+ if (y + h > 200)
+ h = 200 - y;
+ if (x + w > 320)
+ w = 320 - x;
+ //debug(1, "multiget %u,%u %ux%u -> segment: %04x->%04x", x, y, w, h, (uint16)ds, (uint16)es);
+ for(unsigned l = 0; l < h; ++l) {
+ uint8 *src_p = ds.ptr(src + kScreenwidth * l, w);
+ uint8 *dst_p = es.ptr(dst + w * l, w);
+ memcpy(dst_p, src_p, w);
+ }
+ si += w * h;
+ di = src + kScreenwidth * h;
+ cx = 0;
+}
+
+void DreamGenContext::multiput() {
+ unsigned w = (uint8)cl, h = (uint8)ch;
+ unsigned x = (uint16)di, y = (uint16)bx;
+ unsigned src = (uint16)si;
+ unsigned dst = x + y * kScreenwidth;
+ es = data.word(kWorkspace);
+ if (y + h > 200)
+ h = 200 - y;
+ if (x + w > 320)
+ w = 320 - x;
+ //debug(1, "multiput %ux%u -> segment: %04x->%04x", w, h, (uint16)ds, (uint16)es);
+ for(unsigned l = 0; l < h; ++l) {
+ uint8 *src_p = ds.ptr(src + w * l, w);
+ uint8 *dst_p = es.ptr(dst + kScreenwidth * l, w);
+ memcpy(dst_p, src_p, w);
+ }
+ si += w * h;
+ di = dst + kScreenwidth * h;
+ cx = 0;
+}
+
+void DreamGenContext::multidump() {
+ ds = data.word(kWorkspace);
+ int w = (uint8)cl, h = (uint8)ch;
+ int x = (int16)di, y = (int16)bx;
+ unsigned offset = x + y * kScreenwidth;
+ //debug(1, "multidump %ux%u(segment: %04x) -> %d,%d(address: %d)", w, h, (uint16)ds, x, y, offset);
+ engine->blit(ds.ptr(offset, w * h), kScreenwidth, x, y, w, h);
+ si = di = offset + h * kScreenwidth;
+ cx = 0;
+}
+
+void DreamGenContext::worktoscreen() {
+ ds = data.word(kWorkspace);
+ uint size = 320 * 200;
+ engine->blit(ds.ptr(0, size), 320, 0, 0, 320, 200);
+ di = si = size;
+ cx = 0;
+}
+
+void DreamGenContext::printundermon() {
+ engine->printUnderMonitor();
+}
+
+void DreamGenContext::cls() {
+ engine->cls();
+}
+
+void DreamGenContext::frameoutnm() {
+ unsigned w = (uint8)cl, h = (uint8)ch;
+ unsigned pitch = (uint16)dx;
+ unsigned src = (uint16)si;
+ int x = (uint16)di, y = (uint16)bx;
+ unsigned dst = x + y * pitch;
+ //debug(1, "framenm %ux%u[pitch: %u]-> %d,%d, segment: %04x->%04x", w, h, pitch, x, y, (uint16)ds, (uint16)es);
+ for(unsigned l = 0; l < h; ++l) {
+ uint8 *src_p = ds.ptr(src + w * l, w);
+ uint8 *dst_p = es.ptr(dst + pitch * l, w);
+ memcpy(dst_p, src_p, w);
+ }
+ di += dst + pitch * h;
+ si += w * h;
+ cx = 0;
+}
+
+void DreamGenContext::seecommandtail() {
+ data.word(kSoundbaseadd) = 0x220;
+ data.byte(kSoundint) = 5;
+ data.byte(kSounddmachannel) = 1;
+ data.byte(kBrightness) = 1;
+ data.word(kHowmuchalloc) = 0x9360;
+}
+
+void DreamGenContext::randomnumber() {
+ al = engine->randomNumber();
+}
+
+void DreamGenContext::quickquit() {
+ engine->quit();
+}
+
+void DreamGenContext::quickquit2() {
+ engine->quit();
+}
+
+void DreamGenContext::keyboardread() {
+ ::error("keyboardread"); //this keyboard int handler, must never be called
+}
+
+void DreamGenContext::resetkeyboard() {
+}
+
+void DreamGenContext::setkeyboardint() {
+}
+
+void DreamGenContext::readfromfile() {
+ uint16 dst_offset = dx;
+ uint16 size = cx;
+ debug(1, "readfromfile(%04x:%u, %u)", (uint16)ds, dst_offset, size);
+ ax = engine->readFromFile(ds.ptr(dst_offset, size), size);
+ flags._c = false;
+}
+
+void DreamGenContext::closefile() {
+ engine->closeFile();
+ data.byte(kHandle) = 0;
+}
+
+void DreamGenContext::openforsave() {
+ const char *name = (const char *)ds.ptr(dx, 13);
+ debug(1, "openforsave(%s)", name);
+ engine->openSaveFileForWriting(name);
+}
+
+void DreamGenContext::openfilenocheck() {
+ const char *name = (const char *)ds.ptr(dx, 13);
+ debug(1, "checksavefile(%s)", name);
+ bool ok = engine->openSaveFileForReading(name);
+ flags._c = !ok;
+}
+
+void DreamGenContext::openfilefromc() {
+ openfilenocheck();
+}
+
+void DreamGenContext::openfile() {
+ Common::String name = getFilename(*this);
+ debug(1, "opening file: %s", name.c_str());
+ engine->openFile(name);
+ cs.word(kHandle) = 1; //only one handle
+ flags._c = false;
+}
+
+void DreamGenContext::createfile() {
+ ::error("createfile");
+}
+
+void DreamGenContext::dontloadseg() {
+ ax = es.word(di);
+ _add(di, 2);
+ dx = ax;
+ cx = 0;
+ unsigned pos = engine->skipBytes(dx);
+ dx = pos >> 16;
+ ax = pos & 0xffff;
+ flags._c = false;
+}
+
+void DreamGenContext::mousecall() {
+ engine->mouseCall();
+}
+
+void DreamGenContext::setmouse() {
+ data.word(kOldpointerx) = 0xffff;
+}
+
+void DreamGenContext::gettime() {
+ TimeDate t;
+ g_system->getTimeAndDate(t);
+ debug(1, "\tgettime: %02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
+ ch = t.tm_hour;
+ cl = t.tm_min;
+ dh = t.tm_sec;
+ data.byte(kSecondcount) = dh;
+ data.byte(kMinutecount) = cl;
+ data.byte(kHourcount) = ch;
+}
+
+void DreamGenContext::allocatemem() {
+ uint size = (bx + 2) * 16;
+ debug(1, "allocate mem, %u bytes", size);
+ flags._c = false;
+ SegmentRef seg = allocateSegment(size);
+ ax = (uint16)seg;
+ debug(1, "\tsegment address -> %04x", (uint16)ax);
+}
+
+void DreamGenContext::deallocatemem() {
+ uint16 id = (uint16)es;
+ debug(1, "deallocating segment %04x", id);
+ deallocateSegment(id);
+
+ //fixing invalid entries in the sprite table
+ es = data;
+ uint tsize = 16 * 32;
+ uint16 bseg = data.word(kBuffers);
+ if (!bseg)
+ return;
+ SegmentRef buffers(this);
+ buffers = bseg;
+ uint8 *ptr = buffers.ptr(kSpritetable, tsize);
+ for(uint i = 0; i < tsize; i += 32) {
+ uint16 seg = READ_LE_UINT16(ptr + i + 6);
+ //debug(1, "sprite segment = %04x", seg);
+ if (seg == id)
+ memset(ptr + i, 0xff, 32);
+ }
+}
+
+void DreamGenContext::removeemm() {
+ ::error("removeemm");
+}
+
+void DreamGenContext::setupemm() {
+ //good place for early initialization
+ switch(engine->getLanguage()) {
+ case Common::EN_ANY:
+ case Common::EN_GRB:
+ case Common::EN_USA:
+ return;
+ default:
+ data.byte(kForeignrelease) = 1;
+ }
+}
+
+void DreamGenContext::pitinterupt() {
+ ::error("pitinterupt");
+}
+
+void DreamGenContext::getridofpit() {
+ ::error("getridofpit");
+}
+
+void DreamGenContext::setuppit() {
+ ::error("setuppit");
+}
+
+void DreamGenContext::startdmablock() {
+ ::error("startdmablock");
+}
+
+void DreamGenContext::dmaend() {
+ ::error("dmaend");
+}
+
+void DreamGenContext::restoreems() {
+ ::error("restoreems");
+}
+
+void DreamGenContext::saveems() {
+ ::error("saveems");
+}
+
+void DreamGenContext::bothchannels() {
+ ::error("bothchannels");
+}
+
+void DreamGenContext::channel1only() {
+ ::error("channel1only");
+}
+
+void DreamGenContext::channel0only() {
+ ::error("channel0only");
+}
+
+void DreamGenContext::out22c() {
+ ::error("out22c");
+}
+
+void DreamGenContext::soundstartup() {}
+void DreamGenContext::soundend() {}
+void DreamGenContext::interupttest() {}
+void DreamGenContext::disablesoundint() {}
+void DreamGenContext::enablesoundint() {}
+void DreamGenContext::checksoundint() {
+ data.byte(kTestresult) = 1;
+}
+
+void DreamGenContext::setsoundoff() {
+ warning("setsoundoff: STUB");
+}
+
+void DreamGenContext::loadsample() {
+ engine->loadSounds(0, (const char *)data.ptr(dx, 13));
+}
+
+void DreamGenContext::loadsecondsample() {
+ uint8 ch0 = data.byte(kCh0playing);
+ if (ch0 >= 12 && ch0 != 255)
+ cancelch0();
+ uint8 ch1 = data.byte(kCh1playing);
+ if (ch1 >= 12)
+ cancelch1();
+ engine->loadSounds(1, (const char *)data.ptr(dx, 13));
+}
+
+void DreamGenContext::loadspeech() {
+ cancelch1();
+ data.byte(kSpeechloaded) = 0;
+ createname();
+ const char *name = (const char *)data.ptr(di, 13);
+ //warning("name = %s", name);
+ if (engine->loadSpeech(name))
+ data.byte(kSpeechloaded) = 1;
+}
+
+void DreamGenContext::saveseg() {
+ cx = es.word(di);
+ _add(di, 2);
+ savefilewrite();
+}
+
+void DreamGenContext::savefilewrite() {
+ ax = engine->writeToSaveFile(ds.ptr(dx, cx), cx);
+}
+
+void DreamGenContext::savefileread() {
+ ax = engine->readFromSaveFile(ds.ptr(dx, cx), cx);
+}
+
+void DreamGenContext::loadseg() {
+ ax = es.word(di);
+ di += 2;
+
+ uint16 dst_offset = dx;
+ uint16 size = ax;
+
+ debug(1, "loadseg(%04x:%u, %u)", (uint16)ds, dst_offset, size);
+ ax = engine->readFromFile(ds.ptr(dst_offset, size), size);
+ flags._c = false;
+}
+
+void DreamGenContext::error() {
+ ::error("error");
+}
+
+void DreamGenContext::generalerror() {
+ ::error("generalerror");
+}
+
+void DreamGenContext::dosreturn() {
+
+ _cmp(data.byte(kCommandtype), 250);
+ if (!flags.z()) {
+ data.byte(kCommandtype) = 250;
+ al = 46;
+ commandonly();
+ }
+
+ ax = data.word(kMousebutton);
+ _and(ax, 1);
+ if (flags.z())
+ return;
+
+ data.word(kMousebutton) = 0;
+ engine->quit();
+}
+
+void DreamGenContext::set16colpalette() {
+ //fixme: this is a bit hackish, set16colpalette called after initialization and nearly before main loop.
+ engine->enableSavingOrLoading();
+}
+
+void DreamGenContext::mode640x480() {
+ // Video mode 12h: 640x480 pixels, 16 colors, I believe
+ al = 0x12 + 128;
+ ah = 0;
+ initGraphics(640, 480, true);
+}
+
+void DreamGenContext::showgroup() {
+ engine->setPalette();
+}
+
+void DreamGenContext::fadedos() {
+ engine->fadeDos();
+}
+
+void DreamGenContext::doshake() {
+ uint8 &counter = data.byte(kShakecounter);
+ _cmp(counter, 48);
+ if (flags.z())
+ return;
+
+ _add(counter, 1);
+ static const int shakeTable[] = {
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 2, 0, -2, 3, -2,
+ 0, 2, 4, -1, 1, -3, 3, 2,
+ 0, -2, 3, -2, 0, 2, 4, -1,
+
+ 1, -3, 3, 2, 0, -2, 3, -2,
+ 0, 2, 4, -1, 1, -3, 3, 2,
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 2, 0, -2, 3, -2,
+
+ 0, 2, 4, -1, 1, -3, 3, 2,
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 2, 0, -2, 3, -2,
+ 0, 2, 4, -1, 1, -3, 3, 2,
+
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 0,
+ };
+ int offset = shakeTable[counter];
+ engine->setShakePos(offset >= 0? offset: -offset);
+}
+
+void DreamGenContext::vsync() {
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ push(si);
+ push(di);
+ push(es);
+ push(ds);
+ engine->waitForVSync();
+ ds = pop();
+ es = pop();
+ di = pop();
+ si = pop();
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+}
+
+void DreamGenContext::setmode() {
+ vsync();
+ initGraphics(320, 200, false);
+}
+
+void DreamGenContext::showpcx() {
+ Common::String name = getFilename(*this);
+ Common::File pcxFile;
+
+ if (!pcxFile.open(name)) {
+ warning("showpcx: Could not open '%s'", name.c_str());
+ return;
+ }
+
+ uint8 *maingamepal;
+ int i, j;
+
+ // Read the 16-color palette into the 'maingamepal' buffer. Note that
+ // the color components have to be adjusted from 8 to 6 bits.
+
+ pcxFile.seek(16, SEEK_SET);
+ es = data.word(kBuffers);
+ maingamepal = es.ptr(kMaingamepal, 768);
+ pcxFile.read(maingamepal, 48);
+
+ memset(maingamepal + 48, 0xff, 720);
+ for (i = 0; i < 48; i++) {
+ maingamepal[i] >>= 2;
+ }
+
+ // Decode the image data.
+
+ Graphics::Surface *s = g_system->lockScreen();
+ Common::Rect rect(640, 480);
+
+ s->fillRect(rect, 0);
+ pcxFile.seek(128, SEEK_SET);
+
+ for (int y = 0; y < 480; y++) {
+ byte *dst = (byte *)s->getBasePtr(0, y);
+ int decoded = 0;
+
+ while (decoded < 320) {
+ byte col = pcxFile.readByte();
+ byte len;
+
+ if ((col & 0xc0) == 0xc0) {
+ len = col & 0x3f;
+ col = pcxFile.readByte();
+ } else {
+ len = 1;
+ }
+
+ // The image uses 16 colors and is stored as four bit
+ // planes, one for each bit of the color, least
+ // significant bit plane first.
+
+ for (i = 0; i < len; i++) {
+ int plane = decoded / 80;
+ int pos = decoded % 80;
+
+ for (j = 0; j < 8; j++) {
+ byte bit = (col >> (7 - j)) & 1;
+ dst[8 * pos + j] |= (bit << plane);
+ }
+
+ decoded++;
+ }
+ }
+ }
+
+ g_system->unlockScreen();
+ pcxFile.close();
+}
+
+void DreamGenContext::frameoutv() {
+ uint16 pitch = dx;
+ uint16 width = cx & 0xff;
+ uint16 height = cx >> 8;
+ uint16 stride = pitch - width;
+
+ const uint8* src = ds.ptr(si, width * height);
+ uint8* base = es.ptr(di, stride * height);
+ uint8* dst = base + pitch * bx;
+
+ // NB: Original code assumes non-zero width and height, "for" are unneeded, do-while would suffice but would be less readable
+ for (uint16 y = 0; y < height; ++y) {
+ for (uint16 x = 0; x < width; ++x) {
+ uint8 pixel = *src++;
+ if (pixel)
+ *dst = pixel;
+ ++dst;
+ }
+ dst += stride;
+ }
+}
+
+void DreamGenContext::modifychar() {
+ al = engine->modifyChar(al);
+}
+
+} /*namespace dreamgen */
diff --git a/engines/engine.cpp b/engines/engine.cpp
index 210b0b46a3..b952f065ad 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -42,6 +42,7 @@
#include "common/list_intern.h"
#include "common/scummsys.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "gui/debugger.h"
#include "gui/dialog.h"
@@ -95,6 +96,7 @@ Engine::Engine(OSystem *syst)
_targetName(ConfMan.getActiveDomainName()),
_pauseLevel(0),
_pauseStartTime(0),
+ _saveSlotToLoad(-1),
_engineStartTime(_system->getMillis()),
_mainMenuDialog(NULL) {
@@ -216,7 +218,7 @@ void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics:
// Just show warnings then these occur:
#ifdef USE_RGB_COLOR
if (gfxError & OSystem::kTransactionFormatNotSupported) {
- Common::String message = "Could not initialize color format.";
+ Common::String message = _("Could not initialize color format.");
GUI::MessageDialog dialog(message);
dialog.runModal();
@@ -224,7 +226,7 @@ void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics:
#endif
if (gfxError & OSystem::kTransactionModeSwitchFailed) {
- Common::String message = "Could not switch to video mode: '";
+ Common::String message = _("Could not switch to video mode: '");
message += ConfMan.get("gfx_mode");
message += "'.";
@@ -233,12 +235,12 @@ void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics:
}
if (gfxError & OSystem::kTransactionAspectRatioFailed) {
- GUI::MessageDialog dialog("Could not apply aspect ratio setting.");
+ GUI::MessageDialog dialog(_("Could not apply aspect ratio setting."));
dialog.runModal();
}
if (gfxError & OSystem::kTransactionFullscreenFailed) {
- GUI::MessageDialog dialog("Could not apply fullscreen setting.");
+ GUI::MessageDialog dialog(_("Could not apply fullscreen setting."));
dialog.runModal();
}
}
@@ -338,22 +340,22 @@ void Engine::checkCD() {
if (GetDriveType(buffer) == DRIVE_CDROM) {
GUI::MessageDialog dialog(
- "You appear to be playing this game directly\n"
+ _("You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
"and it is therefore recommended that you copy\n"
"the data files to your hard disk instead.\n"
- "See the README file for details.", "OK");
+ "See the README file for details."), _("OK"));
dialog.runModal();
} else {
// If we reached here, the game has audio tracks,
// it's not ran from the CD and the tracks have not
// been ripped.
GUI::MessageDialog dialog(
- "This game has audio tracks in its disk. These\n"
+ _("This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
"an appropriate CD audio extracting tool in\n"
"order to listen to the game's music.\n"
- "See the README file for details.", "OK");
+ "See the README file for details."), _("OK"));
dialog.runModal();
}
#endif
@@ -395,10 +397,36 @@ void Engine::pauseEngineIntern(bool pause) {
void Engine::openMainMenuDialog() {
if (!_mainMenuDialog)
_mainMenuDialog = new MainMenuDialog(this);
+
+ setGameToLoadSlot(-1);
+
runDialog(*_mainMenuDialog);
+
+ // Load savegame after main menu execution
+ // (not from inside the menu loop to avoid
+ // mouse cursor glitches and simliar bugs,
+ // e.g. #2822778).
+ // FIXME: For now we just ignore the return
+ // value, which is quite bad since it could
+ // be a fatal loading error, which renders
+ // the engine unusable.
+ if (_saveSlotToLoad > 0)
+ loadGameState(_saveSlotToLoad);
+
syncSoundSettings();
}
+bool Engine::warnUserAboutUnsupportedGame() {
+ if (ConfMan.getBool("enable_unsupported_game_warning")) {
+ GUI::MessageDialog alert(_("WARNING: The game you are about to start is"
+ " not yet fully supported by ScummVM. As such, it is likely to be"
+ " unstable, and any saves you make might not work in future"
+ " versions of ScummVM."), _("Start anyway"), _("Cancel"));
+ return alert.runModal() == GUI::kMessageOK;
+ }
+ return true;
+}
+
uint32 Engine::getTotalPlayTime() const {
if (!_pauseLevel)
return _system->getMillis() - _engineStartTime;
@@ -425,6 +453,10 @@ int Engine::runDialog(GUI::Dialog &dialog) {
return result;
}
+void Engine::setGameToLoadSlot(int slot) {
+ _saveSlotToLoad = slot;
+}
+
void Engine::syncSoundSettings() {
// Sync the engine with the config manager
int soundVolumeMusic = ConfMan.getInt("music_volume");
diff --git a/engines/engine.h b/engines/engine.h
index d7d971ad97..2796df5c4f 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -82,6 +82,13 @@ private:
*/
int32 _engineStartTime;
+ /**
+ * Save slot selected via global main menu.
+ * This slot will be loaded after main menu execution (not from inside
+ * the menu loop, to avoid bugs like #2822778).
+ */
+ int _saveSlotToLoad;
+
public:
@@ -186,6 +193,15 @@ public:
virtual Common::Error loadGameState(int slot);
/**
+ * Sets the game slot for a savegame to be loaded after global
+ * main menu execution. This is to avoid loading a savegame from
+ * inside the menu loop which causes bugs like #2822778.
+ *
+ * @param slot the slot from which a savestate should be loaded.
+ */
+ void setGameToLoadSlot(int slot);
+
+ /**
* Indicates whether a game state can be loaded.
*/
virtual bool canLoadGameStateCurrently();
@@ -252,6 +268,13 @@ public:
void openMainMenuDialog();
/**
+ * Display a warning to the user that the game is not fully supported.
+ *
+ * @return true if the user chose to start anyway, false otherwise
+ */
+ static bool warnUserAboutUnsupportedGame();
+
+ /**
* Get the total play time.
*
* @return How long the player has been playing in ms.
diff --git a/engines/engines.mk b/engines/engines.mk
index 63e4665d28..07364a5bd3 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -51,6 +51,11 @@ 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
diff --git a/engines/game.cpp b/engines/game.cpp
index a14edb8af4..8ea68bb681 100644
--- a/engines/game.cpp
+++ b/engines/game.cpp
@@ -38,20 +38,15 @@ GameDescriptor::GameDescriptor() {
setVal("description", "");
}
-GameDescriptor::GameDescriptor(const PlainGameDescriptor &pgd) {
- setVal("gameid", pgd.gameid);
- setVal("description", pgd.description);
-}
-
-GameDescriptor::GameDescriptor(const PlainGameDescriptorGUIOpts &pgd) {
+GameDescriptor::GameDescriptor(const PlainGameDescriptor &pgd, uint32 guioptions) {
setVal("gameid", pgd.gameid);
setVal("description", pgd.description);
- if (pgd.guioptions != 0)
- setVal("guioptions", Common::getGameGUIOptionsDescription(pgd.guioptions));
+ if (guioptions != 0)
+ setVal("guioptions", Common::getGameGUIOptionsDescription(guioptions));
}
-GameDescriptor::GameDescriptor(const Common::String &g, const Common::String &d, Common::Language l, Common::Platform p, uint32 guioptions) {
+GameDescriptor::GameDescriptor(const Common::String &g, const Common::String &d, Common::Language l, Common::Platform p, uint32 guioptions, GameSupportLevel gsl) {
setVal("gameid", g);
setVal("description", d);
if (l != Common::UNK_LANG)
@@ -60,6 +55,8 @@ GameDescriptor::GameDescriptor(const Common::String &g, const Common::String &d,
setVal("platform", Common::getPlatformCode(p));
if (guioptions != 0)
setVal("guioptions", Common::getGameGUIOptionsDescription(guioptions));
+
+ setSupportLevel(gsl);
}
void GameDescriptor::setGUIOptions(uint32 guioptions) {
@@ -74,9 +71,6 @@ void GameDescriptor::appendGUIOptions(const Common::String &str) {
}
void GameDescriptor::updateDesc(const char *extra) {
- // TODO: The format used here (LANG/PLATFORM/EXTRA) is not set in stone.
- // We may want to change the order (PLATFORM/EXTRA/LANG, anybody?), or
- // the seperator (instead of '/' use ', ' or ' ').
const bool hasCustomLanguage = (language() != Common::UNK_LANG);
const bool hasCustomPlatform = (platform() != Common::kPlatformUnknown);
const bool hasExtraDesc = (extra && extra[0]);
@@ -102,3 +96,30 @@ void GameDescriptor::updateDesc(const char *extra) {
setVal("description", descr);
}
}
+
+GameSupportLevel GameDescriptor::getSupportLevel() {
+ GameSupportLevel gsl = kStableGame;
+ if (contains("gsl")) {
+ Common::String gslString = getVal("gsl");
+ if (gslString.equals("unstable"))
+ gsl = kUnstableGame;
+ else if (gslString.equals("testing"))
+ gsl = kTestingGame;
+ }
+ return gsl;
+}
+
+void GameDescriptor::setSupportLevel(GameSupportLevel gsl) {
+ switch (gsl) {
+ case kUnstableGame:
+ setVal("gsl", "unstable");
+ break;
+ case kTestingGame:
+ setVal("gsl", "testing");
+ break;
+ case kStableGame:
+ // Fall Through intended
+ default:
+ erase("gsl");
+ }
+}
diff --git a/engines/game.h b/engines/game.h
index f9988c2965..9082d93793 100644
--- a/engines/game.h
+++ b/engines/game.h
@@ -40,24 +40,22 @@ struct PlainGameDescriptor {
};
/**
- * Same as PlainGameDsscriptor except it adds Game GUI options parameter
- * This is a plain struct to make it possible to declare NULL-terminated C arrays
- * consisting of PlainGameDescriptors.
- */
-struct PlainGameDescriptorGUIOpts {
- const char *gameid;
- const char *description;
- uint32 guioptions;
-};
-
-/**
* Given a list of PlainGameDescriptors, returns the first PlainGameDescriptor
* matching the given gameid. If not match is found return 0.
- * The end of the list must marked by a PlainGameDescriptor with gameid equal to 0.
+ * The end of the list must be marked by an entry with gameid 0.
*/
const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list);
/**
+ * Ths is an enum to describe how done a game is. This also indicates what level of support is expected.
+ */
+enum GameSupportLevel {
+ kStableGame = 0, // the game is fully supported
+ kTestingGame, // the game is not supposed to end up in releases yet but is ready for public testing
+ kUnstableGame // the game is not even ready for public testing yet
+};
+
+/**
* A hashmap describing details about a given game. In a sense this is a refined
* version of PlainGameDescriptor, as it also contains a gameid and a description string.
* But in addition, platform and language settings, as well as arbitrary other settings,
@@ -67,22 +65,30 @@ const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const Pla
class GameDescriptor : public Common::StringMap {
public:
GameDescriptor();
- GameDescriptor(const PlainGameDescriptor &pgd);
- GameDescriptor(const PlainGameDescriptorGUIOpts &pgd);
+ GameDescriptor(const PlainGameDescriptor &pgd, uint32 guioptions = 0);
GameDescriptor(const Common::String &gameid,
const Common::String &description,
Common::Language language = Common::UNK_LANG,
Common::Platform platform = Common::kPlatformUnknown,
- uint32 guioptions = 0);
+ uint32 guioptions = 0,
+ GameSupportLevel gsl = kStableGame);
/**
- * Update the description string by appending (LANG/PLATFORM/EXTRA) to it.
+ * Update the description string by appending (EXTRA/PLATFORM/LANG) to it.
+ * Values that are missing are omitted, so e.g. (EXTRA/LANG) would be
+ * added if no platform has been specified but a language and an extra string.
*/
void updateDesc(const char *extra = 0);
void setGUIOptions(uint32 options);
void appendGUIOptions(const Common::String &str);
+ /**
+ * What level of support is expected of this game
+ */
+ GameSupportLevel getSupportLevel();
+ void setSupportLevel(GameSupportLevel gsl);
+
Common::String &gameid() { return getVal("gameid"); }
Common::String &description() { return getVal("description"); }
const Common::String &gameid() const { return getVal("gameid"); }
@@ -102,7 +108,7 @@ public:
GameList(const GameList &list) : Common::Array<GameDescriptor>(list) {}
GameList(const PlainGameDescriptor *g) {
while (g->gameid) {
- push_back(GameDescriptor(g->gameid, g->description));
+ push_back(GameDescriptor(*g));
g++;
}
}
diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp
index be44c05bfb..9a554b5429 100644
--- a/engines/gob/detection.cpp
+++ b/engines/gob/detection.cpp
@@ -22,6 +22,7 @@
#include "base/plugins.h"
#include "engines/advancedDetector.h"
+#include "engines/obsolete.h"
#include "gob/gob.h"
@@ -78,7 +79,7 @@ static const PlainGameDescriptor gobGames[] = {
{0, 0}
};
-static const ADObsoleteGameID obsoleteGameIDsTable[] = {
+static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = {
{"gob1", "gob", kPlatformUnknown},
{"gob2", "gob", kPlatformUnknown},
{0, 0, kPlatformUnknown}
@@ -86,34 +87,20 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
#include "gob/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Gob::gameDescriptions,
- // Size of that superset structure
- sizeof(Gob::GOBGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- gobGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- "gob",
- // List of files for file-based fallback detection (optional)
- Gob::fileBased,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class GobMetaEngine : public AdvancedMetaEngine {
public:
- GobMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ GobMetaEngine() : AdvancedMetaEngine(Gob::gameDescriptions, sizeof(Gob::GOBGameDescription), gobGames) {
+ _singleid = "gob";
+ _guioptions = Common::GUIO_NOLAUNCHLOAD;
+ }
+
+ virtual GameDescriptor findGame(const char *gameid) const {
+ return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable);
+ }
+
+ virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
+ return detectGameFilebased(allFiles, Gob::fileBased);
+ }
virtual const char *getName() const {
return "Gob";
@@ -124,6 +111,11 @@ public:
}
virtual bool hasFeature(MetaEngineFeature f) const;
+
+ virtual Common::Error createInstance(OSystem *syst, Engine **engine) const {
+ Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable);
+ return AdvancedMetaEngine::createInstance(syst, engine);
+ }
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
};
diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h
index 11cca2b65e..1c9811fe9e 100644
--- a/engines/gob/detection_tables.h
+++ b/engines/gob/detection_tables.h
@@ -5202,32 +5202,32 @@ static const GOBGameDescription fallbackDescs[] = {
};
static const ADFileBasedFallback fileBased[] = {
- { &fallbackDescs[ 0], { "intro.stk", "disk1.stk", "disk2.stk", "disk3.stk", "disk4.stk", 0 } },
- { &fallbackDescs[ 1], { "intro.stk", "gob.lic", 0 } },
- { &fallbackDescs[ 2], { "intro.stk", 0 } },
- { &fallbackDescs[ 2], { "intro.stk", "disk2.stk", "disk3.stk", 0 } },
- { &fallbackDescs[ 3], { "intro.stk", "disk2.stk", "disk3.stk", "musmac1.mid", 0 } },
- { &fallbackDescs[ 4], { "intro.stk", "gobnew.lic", 0 } },
- { &fallbackDescs[ 5], { "intro.stk", "scaa.imd", "scba.imd", "scbf.imd", 0 } },
- { &fallbackDescs[ 6], { "intro.stk", "imd.itk", 0 } },
- { &fallbackDescs[ 7], { "intro.stk", "mus_gob3.lic", 0 } },
- { &fallbackDescs[ 8], { "intro.stk", "woodruff.itk", 0 } },
- { &fallbackDescs[ 9], { "intro.stk", "commun1.itk", 0 } },
- { &fallbackDescs[10], { "intro.stk", "commun1.itk", "musmac1.mid", 0 } },
- { &fallbackDescs[11], { "intro.stk", "commun1.itk", "lost.lic", 0 } },
- { &fallbackDescs[12], { "intro.stk", "cd1.itk", "objet1.itk", 0 } },
- { &fallbackDescs[13], { "playtoon.stk", "archi.stk", 0 } },
- { &fallbackDescs[14], { "playtoon.stk", "spirou.stk", 0 } },
- { &fallbackDescs[15], { "playtoon.stk", "chato.stk", 0 } },
- { &fallbackDescs[16], { "playtoon.stk", "manda.stk", 0 } },
- { &fallbackDescs[17], { "playtoon.stk", "wakan.stk", 0 } },
- { &fallbackDescs[18], { "playtoon.stk", "dan.itk" } },
- { &fallbackDescs[19], { "intro.stk", "bambou.itk", 0 } },
- { &fallbackDescs[20], { "disk0.stk", "disk1.stk", "disk2.stk", "disk3.stk", 0 } },
- { &fallbackDescs[21], { "disk1.stk", "disk2.stk", "disk3.stk", 0 } },
- { &fallbackDescs[22], { "adi2.stk", 0 } },
- { &fallbackDescs[23], { "adif41.stk", "adim41.stk", 0 } },
- { &fallbackDescs[24], { "coktelplayer.scn", 0 } },
+ { &fallbackDescs[ 0].desc, { "intro.stk", "disk1.stk", "disk2.stk", "disk3.stk", "disk4.stk", 0 } },
+ { &fallbackDescs[ 1].desc, { "intro.stk", "gob.lic", 0 } },
+ { &fallbackDescs[ 2].desc, { "intro.stk", 0 } },
+ { &fallbackDescs[ 2].desc, { "intro.stk", "disk2.stk", "disk3.stk", 0 } },
+ { &fallbackDescs[ 3].desc, { "intro.stk", "disk2.stk", "disk3.stk", "musmac1.mid", 0 } },
+ { &fallbackDescs[ 4].desc, { "intro.stk", "gobnew.lic", 0 } },
+ { &fallbackDescs[ 5].desc, { "intro.stk", "scaa.imd", "scba.imd", "scbf.imd", 0 } },
+ { &fallbackDescs[ 6].desc, { "intro.stk", "imd.itk", 0 } },
+ { &fallbackDescs[ 7].desc, { "intro.stk", "mus_gob3.lic", 0 } },
+ { &fallbackDescs[ 8].desc, { "intro.stk", "woodruff.itk", 0 } },
+ { &fallbackDescs[ 9].desc, { "intro.stk", "commun1.itk", 0 } },
+ { &fallbackDescs[10].desc, { "intro.stk", "commun1.itk", "musmac1.mid", 0 } },
+ { &fallbackDescs[11].desc, { "intro.stk", "commun1.itk", "lost.lic", 0 } },
+ { &fallbackDescs[12].desc, { "intro.stk", "cd1.itk", "objet1.itk", 0 } },
+ { &fallbackDescs[13].desc, { "playtoon.stk", "archi.stk", 0 } },
+ { &fallbackDescs[14].desc, { "playtoon.stk", "spirou.stk", 0 } },
+ { &fallbackDescs[15].desc, { "playtoon.stk", "chato.stk", 0 } },
+ { &fallbackDescs[16].desc, { "playtoon.stk", "manda.stk", 0 } },
+ { &fallbackDescs[17].desc, { "playtoon.stk", "wakan.stk", 0 } },
+ { &fallbackDescs[18].desc, { "playtoon.stk", "dan.itk" } },
+ { &fallbackDescs[19].desc, { "intro.stk", "bambou.itk", 0 } },
+ { &fallbackDescs[20].desc, { "disk0.stk", "disk1.stk", "disk2.stk", "disk3.stk", 0 } },
+ { &fallbackDescs[21].desc, { "disk1.stk", "disk2.stk", "disk3.stk", 0 } },
+ { &fallbackDescs[22].desc, { "adi2.stk", 0 } },
+ { &fallbackDescs[23].desc, { "adif41.stk", "adim41.stk", 0 } },
+ { &fallbackDescs[24].desc, { "coktelplayer.scn", 0 } },
{ 0, { 0 } }
};
diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp
index bab1975abc..081b48fbad 100644
--- a/engines/gob/inter_fascin.cpp
+++ b/engines/gob/inter_fascin.cpp
@@ -174,7 +174,7 @@ void Inter_Fascination::oFascin_assign(OpFuncParams &params) {
case TYPE_VAR_INT32_AS_INT16:
case TYPE_ARRAY_INT16:
- WRITE_VARO_UINT16(dest + i * 2, _vm->_game->_script->getResultInt());
+ WRITE_VARO_UINT16(dest + i * 2, _vm->_game->_script->getResultInt());
break;
case TYPE_VAR_INT32:
diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp
index d57d2f354b..e05cae354c 100644
--- a/engines/gob/inter_playtoons.cpp
+++ b/engines/gob/inter_playtoons.cpp
@@ -22,6 +22,7 @@
#include "common/endian.h"
#include "common/str.h"
+#include "common/translation.h"
#include "gui/message.h"
@@ -252,7 +253,7 @@ void Inter_Playtoons::oPlaytoons_readData(OpFuncParams &params) {
WRITE_VAR(1, 1);
if (!_vm->_saveLoad->load(file.c_str(), dataVar, size, offset)) {
- GUI::MessageDialog dialog("Failed to load game state from file.");
+ GUI::MessageDialog dialog(_("Failed to load game state from file."));
dialog.runModal();
} else
WRITE_VAR(1, 0);
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 84cae3b380..2fea18343d 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -22,6 +22,7 @@
#include "common/endian.h"
#include "common/str.h"
+#include "common/translation.h"
#include "gui/message.h"
@@ -1279,7 +1280,7 @@ void Inter_v2::o2_readData(OpFuncParams &params) {
if (!_vm->_saveLoad->load(file, dataVar, size, offset)) {
- GUI::MessageDialog dialog("Failed to load game state from file.");
+ GUI::MessageDialog dialog(_("Failed to load game state from file."));
dialog.runModal();
} else
@@ -1349,7 +1350,7 @@ void Inter_v2::o2_writeData(OpFuncParams &params) {
if (!_vm->_saveLoad->save(file, dataVar, size, offset)) {
- GUI::MessageDialog dialog("Failed to save game state to file.");
+ GUI::MessageDialog dialog(_("Failed to save game state to file."));
dialog.runModal();
} else
diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp
index ed371737bd..c0e8978afd 100644
--- a/engines/gob/inter_v5.cpp
+++ b/engines/gob/inter_v5.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "common/translation.h"
+
#include "gui/message.h"
#include "gob/gob.h"
@@ -102,7 +104,7 @@ void Inter_v5::o5_deleteFile() {
if (mode == SaveLoad::kSaveModeSave) {
if (!_vm->_saveLoad->deleteFile(file)) {
- GUI::MessageDialog dialog("Failed to delete file.");
+ GUI::MessageDialog dialog(_("Failed to delete file."));
dialog.runModal();
}
diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp
index e2c952952d..7fb3104162 100644
--- a/engines/gob/video_v6.cpp
+++ b/engines/gob/video_v6.cpp
@@ -124,7 +124,7 @@ void Video_v6::drawYUV(Surface &destDesc, int16 x, int16 y,
Pixel dstRow = dst;
int nextChromaLine = (i < ((height - 1) & ~3) ) ? dataWidth : 0;
-
+
for (int j = 0; j < width; j++, dstRow++) {
int nextChromaColumn = (j < ((width - 1) & ~3)) ? 1 : 0;
diff --git a/engines/groovie/detection.cpp b/engines/groovie/detection.cpp
index 0dd510abca..62887bac1e 100644
--- a/engines/groovie/detection.cpp
+++ b/engines/groovie/detection.cpp
@@ -131,7 +131,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"11h", "",
AD_ENTRY1s("disk.1", "5c0428cd3659fc7bbcd0aa16485ed5da", 227),
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS,
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE,
Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM
},
kGroovieV2, 1
@@ -142,7 +142,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"11h", "Demo",
AD_ENTRY1s("disk.1", "aacb32ce07e0df2894bd83a3dee40c12", 70),
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, Common::GUIO_NOLAUNCHLOAD |
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, Common::GUIO_NOLAUNCHLOAD |
Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM
},
kGroovieV2, 1
@@ -153,7 +153,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"11h", "Making Of",
AD_ENTRY1s("disk.1", "5c0428cd3659fc7bbcd0aa16485ed5da", 227),
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD
},
kGroovieV2, 2
},
@@ -163,7 +163,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"clandestiny", "Trailer",
AD_ENTRY1s("disk.1", "5c0428cd3659fc7bbcd0aa16485ed5da", 227),
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD
},
kGroovieV2, 3
},
@@ -173,7 +173,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"clandestiny", "",
AD_ENTRY1s("disk.1", "f79fc1515174540fef6a34132efc4c53", 76),
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, Common::GUIO_NOMIDI
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, Common::GUIO_NOMIDI
},
kGroovieV2, 1
},
@@ -183,7 +183,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"unclehenry", "",
AD_ENTRY1s("disk.1", "0e1b1d3cecc4fc7efa62a968844d1f7a", 72),
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, Common::GUIO_NOMIDI
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, Common::GUIO_NOMIDI
},
kGroovieV2, 1
},
@@ -193,7 +193,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"tlc", "",
AD_ENTRY1s("disk.1", "32a1afa68478f1f9d2b25eeea427f2e3", 84),
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, Common::GUIO_NOMIDI
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, Common::GUIO_NOMIDI
},
kGroovieV2, 1
},
@@ -202,35 +202,22 @@ static const GroovieGameDescription gameDescriptions[] = {
{AD_TABLE_END_MARKER, kGroovieT7G, 0}
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)gameDescriptions,
- // Size of that superset structure
- sizeof(GroovieGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- groovieGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "groovie",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- kADFlagUseExtraAsHint,
- // Additional GUI options (for every game}
- Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
-
class GroovieMetaEngine : public AdvancedMetaEngine {
public:
- GroovieMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ GroovieMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(GroovieGameDescription), groovieGames) {
+ _singleid = "groovie";
+
+ // Use kADFlagUseExtraAsHint in order to distinguish the 11th hour from
+ // its "Making of" as well as the Clandestiny Trailer; they all share
+ // the same MD5.
+ // TODO: Is this the only reason, or are there others (like the three
+ // potentially sharing a single directory) ? In the former case, then
+ // perhaps a better solution would be to add additional files
+ // to the detection entries. In the latter case, this TODO should be
+ // replaced with an according explanation.
+ _flags = kADFlagUseExtraAsHint;
+ _guioptions = Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX;
+ }
const char *getName() const {
return "Groovie";
diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index 33fc986193..c6e990dfcf 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -801,17 +801,17 @@ bool MusicPlayerIOS::load(uint32 fileref, bool loop) {
19468 ambient (but not 69, amb b. odd)
19470 puzzle
19471
- 19473
+ 19473
19475 coffins or blood pump
19476 blood pump or coffins
19493
19499 chapel
19509 downstair ambient
19510 bedroom 'skip 3 and 5' puzzle (should loop from partway?)
- 19514
+ 19514
19515 bathroom drain teeth
*/
- if ((fileref >= 19462 && fileref <= 19468) ||
+ if ((fileref >= 19462 && fileref <= 19468) ||
fileref == 19470 || fileref == 19471 ||
fileref == 19473 || fileref == 19475 ||
fileref == 19476 || fileref == 19493 ||
@@ -849,7 +849,7 @@ bool MusicPlayerIOS::load(uint32 fileref, bool loop) {
updateVolume();
// Play!
- _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handle, audStream);
+ _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handle, audStream);
return true;
}
diff --git a/engines/groovie/player.h b/engines/groovie/player.h
index d8135a99b2..c9258ffdbd 100644
--- a/engines/groovie/player.h
+++ b/engines/groovie/player.h
@@ -53,8 +53,8 @@ protected:
Common::SeekableReadStream *_file;
uint16 _flags;
Audio::QueuingAudioStream *_audioStream;
-
-
+
+
private:
// Synchronization stuff
bool _begunPlaying;
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index b52a8723fc..f87e6bb91b 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -36,6 +36,7 @@
#include "common/events.h"
#include "common/file.h"
#include "common/macresman.h"
+#include "common/translation.h"
#include "gui/message.h"
@@ -413,7 +414,7 @@ void Script::savegame(uint slot) {
if (!file) {
debugC(9, kGroovieDebugScript, "Save file pointer is null");
- GUI::MessageDialog dialog("Failed to save game", "OK");
+ GUI::MessageDialog dialog(_("Failed to save game"), _("OK"));
dialog.runModal();
return;
}
diff --git a/engines/hugo/console.cpp b/engines/hugo/console.cpp
index 0a67b5cd0a..19fd91e3fa 100644
--- a/engines/hugo/console.cpp
+++ b/engines/hugo/console.cpp
@@ -64,8 +64,8 @@ bool HugoConsole::Cmd_gotoScreen(int argc, const char **argv) {
if ((argc != 2) || (strToInt(argv[1]) > _vm->_numScreens)){
DebugPrintf("Usage: %s <screen number>\n", argv[0]);
return true;
- }
-
+ }
+
_vm->_scheduler->newScreen(strToInt(argv[1]));
return false;
}
@@ -78,7 +78,7 @@ bool HugoConsole::Cmd_listScreens(int argc, const char **argv) {
DebugPrintf("Usage: %s\n", argv[0]);
return true;
}
-
+
DebugPrintf("Available screens for this game are:\n");
for (int i = 0; i < _vm->_numScreens; i++)
DebugPrintf("%2d - %s\n", i, _vm->_text->getScreenNames(i));
@@ -93,7 +93,7 @@ bool HugoConsole::Cmd_listObjects(int argc, const char **argv) {
DebugPrintf("Usage: %s\n", argv[0]);
return true;
}
-
+
DebugPrintf("Available objects for this game are:\n");
for (int i = 0; i < _vm->_object->_numObj; i++) {
if (_vm->_object->_objects[i].genericCmd & TAKE)
@@ -110,7 +110,7 @@ bool HugoConsole::Cmd_getObject(int argc, const char **argv) {
DebugPrintf("Usage: %s <object number>\n", argv[0]);
return true;
}
-
+
if (_vm->_object->_objects[strToInt(argv[1])].genericCmd & TAKE)
_vm->_parser->takeObject(&_vm->_object->_objects[strToInt(argv[1])]);
else
@@ -127,7 +127,7 @@ bool HugoConsole::Cmd_getAllObjects(int argc, const char **argv) {
DebugPrintf("Usage: %s\n", argv[0]);
return true;
}
-
+
for (int i = 0; i < _vm->_object->_numObj; i++) {
if (_vm->_object->_objects[i].genericCmd & TAKE)
_vm->_parser->takeObject(&_vm->_object->_objects[i]);
diff --git a/engines/hugo/detection.cpp b/engines/hugo/detection.cpp
index 25b8b16084..f70a21aa8f 100644
--- a/engines/hugo/detection.cpp
+++ b/engines/hugo/detection.cpp
@@ -131,34 +131,10 @@ static const HugoGameDescription gameDescriptions[] = {
{AD_TABLE_END_MARKER, kGameTypeNone}
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)gameDescriptions,
- // Size of that superset structure
- sizeof(HugoGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- hugoGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class HugoMetaEngine : public AdvancedMetaEngine {
public:
- HugoMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ HugoMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(HugoGameDescription), hugoGames) {
+ }
const char *getName() const {
return "Hugo";
diff --git a/engines/hugo/dialogs.cpp b/engines/hugo/dialogs.cpp
index 6c816141f7..c43cdd7b46 100644
--- a/engines/hugo/dialogs.cpp
+++ b/engines/hugo/dialogs.cpp
@@ -95,15 +95,15 @@ void TopMenu::reflowLayout() {
_recallButton->resize(x * scale, y * scale, kButtonWidth * scale, kButtonHeight * scale);
x += kButtonWidth + kButtonPad;
-
+
_turboButton->resize(x * scale, y * scale, kButtonWidth * scale, kButtonHeight * scale);
x += kButtonWidth + kButtonPad;
x += kButtonSpace;
-
+
_lookButton->resize(x * scale, y * scale, kButtonWidth * scale, kButtonHeight * scale);
x += kButtonWidth + kButtonPad;
-
+
_inventButton->resize(x * scale, y * scale, kButtonWidth * scale, kButtonHeight * scale);
x += kButtonWidth + kButtonPad;
@@ -133,7 +133,7 @@ void TopMenu::loadBmpArr(Common::SeekableReadStream &in) {
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);
@@ -153,7 +153,7 @@ void TopMenu::loadBmpArr(Common::SeekableReadStream &in) {
*dst++ = *src++;
}
}
-
+
in.skip(bmpSize);
}
}
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp
index c716e80d87..2d35bb0448 100644
--- a/engines/hugo/display.cpp
+++ b/engines/hugo/display.cpp
@@ -736,7 +736,7 @@ overlayState_t Screen_v1d::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) {
uint16 index = (uint16)(dst_p - _frontBuffer) >> 3;
for (int i = 0; i < seq_p->lines-y; i++) { // Each line in object
- if (_vm->_object->getBaseBoundary(index)) // If any overlay base byte is non-zero then the object is foreground, else back.
+ if (_vm->_object->getBaseBoundary(index)) // If any overlay base byte is non-zero then the object is foreground, else back.
return kOvlForeground;
index += kCompLineSize;
}
diff --git a/engines/hugo/file_v1d.cpp b/engines/hugo/file_v1d.cpp
index 9ebd9d284c..0795923536 100644
--- a/engines/hugo/file_v1d.cpp
+++ b/engines/hugo/file_v1d.cpp
@@ -62,7 +62,7 @@ void FileManager_v1d::readOverlay(const int screenNum, image_pt image, const ovl
Common::String buf = Common::String(_vm->_text->getScreenNames(screenNum)) + Common::String(ovl_ext[overlayType]);
if (!Common::File::exists(buf)) {
- memset(image, 0, sizeof(image));
+ memset(image, 0, kOvlSize);
warning("File not found: %s", buf.c_str());
return;
}
diff --git a/engines/hugo/file_v1w.cpp b/engines/hugo/file_v1w.cpp
index eb2226f18a..162019dd2e 100644
--- a/engines/hugo/file_v1w.cpp
+++ b/engines/hugo/file_v1w.cpp
@@ -80,7 +80,7 @@ void FileManager_v1w::readOverlay(const int screenNum, image_pt image, ovl_t ove
break;
}
if (i == 0) {
- memset(image, 0, sizeof(image));
+ memset(image, 0, kOvlSize);
return;
}
_sceneryArchive1.read(tmpImage, kOvlSize);
diff --git a/engines/hugo/file_v2d.cpp b/engines/hugo/file_v2d.cpp
index 2a663edcfa..7e44e756d5 100644
--- a/engines/hugo/file_v2d.cpp
+++ b/engines/hugo/file_v2d.cpp
@@ -136,7 +136,7 @@ void FileManager_v2d::readOverlay(const int screenNum, image_pt image, ovl_t ove
break;
}
if (i == 0) {
- memset(image, 0, sizeof(image));
+ memset(image, 0, kOvlSize);
return;
}
diff --git a/engines/hugo/file_v3d.cpp b/engines/hugo/file_v3d.cpp
index 7ac0ffc48a..69371bb030 100644
--- a/engines/hugo/file_v3d.cpp
+++ b/engines/hugo/file_v3d.cpp
@@ -143,7 +143,7 @@ void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t ove
break;
}
if (i == 0) {
- memset(image, 0, sizeof(image));
+ memset(image, 0, kOvlSize);
return;
}
@@ -182,7 +182,7 @@ void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t ove
break;
}
if (i == 0) {
- memset(image, 0, sizeof(image));
+ memset(image, 0, kOvlSize);
return;
}
diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp
index 10d61f25a2..df8abf32eb 100644
--- a/engines/hugo/hugo.cpp
+++ b/engines/hugo/hugo.cpp
@@ -299,7 +299,7 @@ Common::Error HugoEngine::run() {
_status.helpFl = false;
_file->instructions();
}
-
+
_mouse->mouseHandler(); // Mouse activity - adds to display list
_screen->displayList(kDisplayDisplay); // Blit the display list to screen
_status.doQuitFl |= shouldQuit(); // update game quit flag
@@ -315,7 +315,7 @@ void HugoEngine::initMachine() {
_object->readObjectImages(); // Read all object images
if (_platform == Common::kPlatformWindows)
_file->readUIFImages(); // Read all uif images (only in Win versions)
-
+
_sound->initPcspkrPlayer();
}
@@ -463,7 +463,7 @@ bool HugoEngine::loadHugoDat() {
if (varnt == _gameVariant) {
_numStates = numElem;
_screenStates = (byte *)malloc(sizeof(byte) * numElem);
- memset(_screenStates, 0, sizeof(_screenStates));
+ memset(_screenStates, 0, sizeof(byte) * numElem);
}
}
diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h
index 81d194f1d6..125819a39b 100644
--- a/engines/hugo/hugo.h
+++ b/engines/hugo/hugo.h
@@ -177,7 +177,7 @@ struct status_t { // Game status (not saved)
bool recallFl; // Toolbar "recall" button pressed
bool newScreenFl; // New screen just loaded in dib_a
bool godModeFl; // Allow DEBUG features in live version
- bool showBoundariesFl; // Flag used to show and hide boundaries,
+ bool showBoundariesFl; // Flag used to show and hide boundaries,
// used by the console
bool doQuitFl;
bool skipIntroFl;
diff --git a/engines/hugo/inventory.h b/engines/hugo/inventory.h
index de9e4cd1f0..666cc37b51 100644
--- a/engines/hugo/inventory.h
+++ b/engines/hugo/inventory.h
@@ -56,7 +56,7 @@ private:
HugoEngine *_vm;
static const int kStepDy = 8; // Pixels per step movement
-
+
int16 _firstIconId; // Index of first icon to display
int16 *_invent;
istate_t _inventoryState; // Inventory icon bar state
diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp
index e888a1d998..e5c7b4bf90 100644
--- a/engines/hugo/object.cpp
+++ b/engines/hugo/object.cpp
@@ -157,7 +157,7 @@ void ObjectHandler::useObject(int16 objId) {
if (inventObjId == use->objId) {
// Look for secondary object, if found use matching verb
bool foundFl = false;
-
+
for (target_t *target = use->targets; target->nounIndex != 0; target++)
if (target->nounIndex == obj->nounIndex) {
foundFl = true;
@@ -425,7 +425,7 @@ void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
}
for (int i = 0; i < numElem; i++) {
- if (varnt == _vm->_gameVariant)
+ if (varnt == _vm->_gameVariant)
readUse(in, _uses[i]);
else {
readUse(in, tmpUse);
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 4a53d67377..38a8e4e3ff 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -60,7 +60,7 @@ Parser::~Parser() {
uint16 Parser::getCmdDefaultVerbIdx(const uint16 index) const {
return _cmdList[index][0].verbIndex;
}
-
+
/**
* Read a cmd structure from Hugo.dat
*/
@@ -235,7 +235,7 @@ void Parser::charHandler() {
if (_cmdLineIndex >= kMaxLineSize) {
//MessageBeep(MB_ICONASTERISK);
warning("STUB: MessageBeep() - Command line too long");
- } else if (isprint(c)) {
+ } else if (isprint(static_cast<unsigned char>(c))) {
_cmdLine[_cmdLineIndex++] = c;
_cmdLine[_cmdLineIndex] = '\0';
}
@@ -391,6 +391,8 @@ void Parser::command(const char *format, ...) {
va_list marker;
va_start(marker, format);
+// TODO:
+// _vm->_line = Common::String::vformat(format, marker);
vsprintf(_vm->_line, format, marker);
va_end(marker);
diff --git a/engines/hugo/parser.h b/engines/hugo/parser.h
index faa6dc2303..f8b9d9f13b 100644
--- a/engines/hugo/parser.h
+++ b/engines/hugo/parser.h
@@ -81,9 +81,9 @@ public:
virtual ~Parser();
bool isWordPresent(char **wordArr) const;
-
+
uint16 getCmdDefaultVerbIdx(const uint16 index) const;
-
+
void charHandler();
void command(const char *format, ...);
void freeParser();
diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index a099bec21c..d1b4aa6a9c 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -1040,7 +1040,7 @@ void Scheduler::saveActions(Common::WriteStream *f) const {
* Find the index in the action list to be able to serialize the action to save game
*/
void Scheduler::findAction(const act* action, int16* index, int16* subElem) {
-
+
assert(index && subElem);
if (!action) {
*index = -1;
@@ -1106,7 +1106,7 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
else
_events[i].action = (act*)&_actListArr[index][subElem];
- _events[i].localActionFl = (f->readByte() == 1) ? true : false;
+ _events[i].localActionFl = (f->readByte() == 1) ? true : false;
_events[i].time = f->readUint32BE();
int16 prevIndex = f->readSint16BE();
diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h
index e3107809cf..60d51f0673 100644
--- a/engines/hugo/schedule.h
+++ b/engines/hugo/schedule.h
@@ -616,7 +616,7 @@ public:
protected:
virtual const char *getCypher() const;
-
+
void promptAction(act *action);
};
diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp
index 9473536a47..1fea1f4343 100644
--- a/engines/hugo/sound.cpp
+++ b/engines/hugo/sound.cpp
@@ -127,7 +127,7 @@ SoundHandler::SoundHandler(HugoEngine *vm) : _vm(vm) {
curPriority = 0;
pcspkrTimer = 0;
pcspkrOctave = 3;
- pcspkrNoteDuration = 2;
+ pcspkrNoteDuration = 2;
}
SoundHandler::~SoundHandler() {
@@ -290,7 +290,7 @@ void SoundHandler::pcspkr_player() {
} else if (pcspkrTimer >= 0) { // Note still going
return;
}
-
+
// Time to play next note
do {
cmd_note = true;
diff --git a/engines/hugo/util.cpp b/engines/hugo/util.cpp
index a936a23de1..6dc9890c3a 100644
--- a/engines/hugo/util.cpp
+++ b/engines/hugo/util.cpp
@@ -119,7 +119,7 @@ char *strlwr(char *buffer) {
char *result = buffer;
while (*buffer != '\0') {
- if (isupper(*buffer))
+ if (isupper(static_cast<unsigned char>(*buffer)))
*buffer = tolower(*buffer);
buffer++;
}
diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp
index 6db2e45b0e..84bda3f3fd 100644
--- a/engines/kyra/animator_mr.cpp
+++ b/engines/kyra/animator_mr.cpp
@@ -449,11 +449,10 @@ void KyraEngine_MR::showIdleAnim() {
"A", "R", "R", "FR", "FX", "FL", "L", "L"
};
- char filename[14];
- snprintf(filename, 14, "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _characterShapeFile);
+ Common::String filename = Common::String::format( "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _characterShapeFile);
- if (_res->exists(filename))
- runAnimationScript(filename, 1, 1, 1, 1);
+ if (_res->exists(filename.c_str()))
+ runAnimationScript(filename.c_str(), 1, 1, 1, 1);
}
_nextIdleType = !_nextIdleType;
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index d0baf8a133..e8dd9e9a15 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -71,11 +71,18 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) {
}
if (_vm->game() != GI_KYRA1 && _vm->resource()->getFileSize(argv[1]) != 768) {
- uint8 buffer[320*200];
+ uint8 *buffer = (uint8 *)malloc(320 * 200 * sizeof(uint8));
+ if (!buffer) {
+ DebugPrintf("ERROR: Cannot allocate buffer for screen region!\n");
+ return true;
+ }
+
_vm->screen()->copyRegionToBuffer(5, 0, 0, 320, 200, buffer);
_vm->screen()->loadBitmap(argv[1], 5, 5, 0);
palette.copy(_vm->screen()->getCPagePtr(5), 0, 256);
_vm->screen()->copyBlockToPage(5, 0, 0, 320, 200, buffer);
+
+ free(buffer);
} else if (!_vm->screen()->loadPalette(argv[1], palette)) {
DebugPrintf("ERROR: Palette '%s' not found!\n", argv[1]);
return true;
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 47a086e08c..a6af584fb8 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -47,37 +47,15 @@ const char * const directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)adGameDescs,
- // Size of that superset structure
- sizeof(KYRAGameDescription),
- // Number of bytes to compute MD5 sum for
- 1024 * 1024,
- // List of all engine targets
- gameList,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
} // End of anonymous namespace
class KyraMetaEngine : public AdvancedMetaEngine {
public:
- KyraMetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ KyraMetaEngine() : AdvancedMetaEngine(adGameDescs, sizeof(KYRAGameDescription), gameList) {
+ _md5Bytes = 1024 * 1024;
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ }
const char *getName() const {
return "Kyra";
}
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index 8a948eff00..47a3c4362a 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -47,6 +47,7 @@ namespace {
#define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, true, false, Kyra::GI_KYRA3)
#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, false, Kyra::GI_LOL)
+#define LOL_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, Kyra::GI_LOL)
#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, Kyra::GI_LOL)
#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, true, Kyra::GI_LOL)
#define LOL_PC98_SJIS_FLAGS FLAGS(false, false, false, true, true, false, false, Kyra::GI_LOL)
@@ -1056,6 +1057,109 @@ const KYRAGameDescription adGameDescs[] = {
LOL_CD_FLAGS
},
+ // Italian fan translation
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
{
{
"lol",
@@ -1222,7 +1326,6 @@ const KYRAGameDescription adGameDescs[] = {
LOL_KYRA2_DEMO_FLAGS
},
#endif // ENABLE_LOL
-
{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0) }
};
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index b9477c950a..29cbe20b23 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -375,7 +375,7 @@ void GUI::updateSaveList(bool excludeQuickSaves) {
s1 = (*i)[i->size()-3];
s2 = (*i)[i->size()-2];
s3 = (*i)[i->size()-1];
- if (!isdigit(s1) || !isdigit(s2) || !isdigit(s3))
+ if (!isdigit(static_cast<unsigned char>(s1)) || !isdigit(static_cast<unsigned char>(s2)) || !isdigit(static_cast<unsigned char>(s3)))
continue;
s1 -= '0';
s2 -= '0';
@@ -643,32 +643,31 @@ void MainMenu::printString(const char *format, int x, int y, int col1, int col2,
if (!format)
return;
- char string[512];
va_list vaList;
va_start(vaList, flags);
- vsprintf(string, format, vaList);
+ Common::String string = Common::String::vformat(format, vaList);
va_end(vaList);
if (flags & 1)
- x -= _screen->getTextWidth(string) >> 1;
+ x -= _screen->getTextWidth(string.c_str()) >> 1;
if (flags & 2)
- x -= _screen->getTextWidth(string);
+ x -= _screen->getTextWidth(string.c_str());
if (_vm->gameFlags().use16ColorMode)
flags &= 3;
if (flags & 4) {
- _screen->printText(string, x - 1, y, _static.altColor, col2);
- _screen->printText(string, x, y + 1, _static.altColor, col2);
+ _screen->printText(string.c_str(), x - 1, y, _static.altColor, col2);
+ _screen->printText(string.c_str(), x, y + 1, _static.altColor, col2);
}
if (flags & 8) {
- _screen->printText(string, x - 1, y, 227, col2);
- _screen->printText(string, x, y + 1, 227, col2);
+ _screen->printText(string.c_str(), x - 1, y, 227, col2);
+ _screen->printText(string.c_str(), x, y + 1, 227, col2);
}
- _screen->printText(string, x, y, col1, col2);
+ _screen->printText(string.c_str(), x, y, col1, col2);
}
} // End of namespace Kyra
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 4c4dc50503..fb11040168 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -2806,15 +2806,18 @@ int GUI_LoL::clickedOptionsMenu(Button *button) {
case 0xfff3:
_vm->_configVoice ^= 3;
break;
- case 0x4072:
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%02d.%s", _vm->_currentLevel, _vm->_languageExt[_vm->_lang]);
+ case 0x4072: {
+ Common::String filename;
+ filename = Common::String::format("LEVEL%02d.%s", _vm->_currentLevel, _vm->_languageExt[_vm->_lang]);
delete[] _vm->_levelLangFile;
- _vm->_levelLangFile = _vm->resource()->fileData(filename, 0);
- snprintf(filename, sizeof(filename), "LANDS.%s", _vm->_languageExt[_vm->_lang]);
+ _vm->_levelLangFile = _vm->resource()->fileData(filename.c_str(), 0);
+ filename = Common::String::format("LANDS.%s", _vm->_languageExt[_vm->_lang]);
delete[] _vm->_landsFile;
- _vm->_landsFile = _vm->resource()->fileData(filename, 0);
+ _vm->_landsFile = _vm->resource()->fileData(filename.c_str(), 0);
_newMenu = _lastMenu;
+ } break;
+ default:
+ // TODO: Is there anything we should do if we hit this case?
break;
}
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index 25a77c6cc8..32eb02e06d 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -717,25 +717,25 @@ void KyraEngine_MR::showAlbum() {
}
void KyraEngine_MR::loadAlbumPage() {
- char filename[16];
+ Common::String filename;
int num = _album.curPage / 2;
if (num == 0) {
- strcpy(filename, "ALBUM0.CPS");
+ filename = "ALBUM0.CPS";
} else if (num >= 1 && num <= 6) {
--num;
num %= 2;
- snprintf(filename, 16, "ALBUM%d.CPS", num+1);
+ filename = Common::String::format("ALBUM%d.CPS", num+1);
} else {
- strcpy(filename, "ALBUM3.CPS");
+ filename = "ALBUM3.CPS";
}
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 4, Screen::CR_NO_P_CHECK);
- _screen->loadBitmap(filename, 3, 3, 0);
+ _screen->loadBitmap(filename.c_str(), 3, 3, 0);
}
void KyraEngine_MR::loadAlbumPageWSA() {
- char filename[16];
+ Common::String filename;
_album.leftPage.curFrame = 0;
_album.leftPage.maxFrame = 0;
@@ -746,14 +746,14 @@ void KyraEngine_MR::loadAlbumPageWSA() {
_album.rightPage.wsa->close();
if (_album.curPage) {
- snprintf(filename, 16, "PAGE%x.WSA", _album.curPage);
- _album.leftPage.wsa->open(filename, 1, 0);
+ filename = Common::String::format("PAGE%x.WSA", _album.curPage);
+ _album.leftPage.wsa->open(filename.c_str(), 1, 0);
_album.leftPage.maxFrame = _album.leftPage.wsa->frames()-1;
}
if (_album.curPage != 14) {
- snprintf(filename, 16, "PAGE%x.WSA", _album.curPage+1);
- _album.rightPage.wsa->open(filename, 1, 0);
+ 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;
}
}
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 9a4f7bc42e..5c58e6e3ed 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -503,14 +503,6 @@ void KyraEngine_HoF::runLoop() {
int inputFlag = checkInput(_buttonList, true);
removeInputTop();
- if (_updateHandItemCursor) {
- // This works around an issue which would occur when setHandItem(_itemInHand)
- // was called from inside loadGameState(). When loading via GMM the
- // mouse cursor would not be set correctly.
- _updateHandItemCursor = false;
- setHandItem(_itemInHand);
- }
-
update();
if (inputFlag == 198 || inputFlag == 199) {
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index ee67062cdd..7f356f34c1 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -821,14 +821,6 @@ void KyraEngine_LoK::updateMousePointer(bool forceUpdate) {
newY = 4;
}
- if (_updateHandItemCursor) {
- // This works around an issue which would occur when setHandItem(_itemInHand)
- // was called from inside loadGameState(). When loading via GMM the
- // mouse cursor would not be set correctly.
- _updateHandItemCursor = false;
- setHandItem(_itemInHand);
- }
-
if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) {
_mouseState = newMouseState;
_screen->hideMouse();
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 4ce5c5b2cf..f5bcd04ea0 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -366,10 +366,9 @@ void KyraEngine_MR::uninitMainMenu() {
void KyraEngine_MR::playVQA(const char *name) {
VQAMovie vqa(this, _system);
- char filename[20];
- snprintf(filename, sizeof(filename), "%s%d.VQA", name, _configVQAQuality);
+ Common::String filename = Common::String::format("%s%d.VQA", name, _configVQAQuality);
- if (vqa.open(filename)) {
+ if (vqa.open(filename.c_str())) {
for (int i = 0; i < 4; ++i) {
if (i != _musicSoundChannel)
_soundDigital->stopSound(i);
@@ -444,12 +443,11 @@ void KyraEngine_MR::fadeOutMusic(int ticks) {
void KyraEngine_MR::snd_playSoundEffect(int item, int volume) {
if (_sfxFileMap[item*2+0] != 0xFF) {
- char filename[16];
assert(_sfxFileMap[item*2+0] < _sfxFileListSize);
- snprintf(filename, 16, "%s", _sfxFileList[_sfxFileMap[item*2+0]]);
+ Common::String filename = Common::String::format("%s", _sfxFileList[_sfxFileMap[item*2+0]]);
uint8 priority = _sfxFileMap[item*2+1];
- _soundDigital->playSound(filename, priority, Audio::Mixer::kSFXSoundType, volume);
+ _soundDigital->playSound(filename.c_str(), priority, Audio::Mixer::kSFXSoundType, volume);
}
}
@@ -458,11 +456,10 @@ void KyraEngine_MR::playVoice(int high, int low) {
}
void KyraEngine_MR::snd_playVoiceFile(int file) {
- char filename[16];
- snprintf(filename, 16, "%.08u", (uint)file);
+ Common::String filename = Common::String::format("%.08u", (uint)file);
if (speechEnabled())
- _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255);
+ _voiceSoundChannel = _soundDigital->playSound(filename.c_str(), 0xFE, Audio::Mixer::kSpeechSoundType, 255);
}
bool KyraEngine_MR::snd_voiceIsPlaying() {
@@ -911,14 +908,6 @@ void KyraEngine_MR::runLoop() {
int inputFlag = checkInput(_mainButtonList, true);
removeInputTop();
- if (_updateHandItemCursor) {
- // This works around an issue which would occur when setHandItem(_itemInHand)
- // was called from inside loadGameState(). When loading via GMM the
- // mouse cursor would not be set correctly.
- _updateHandItemCursor = false;
- setHandItem(_itemInHand);
- }
-
update();
_timer->update();
@@ -1242,26 +1231,14 @@ void KyraEngine_MR::restoreGfxRect32x32(int x, int y) {
#pragma mark -
-char *KyraEngine_MR::appendLanguage(char *buf, int lang, int bufSize) {
- assert(lang < _languageExtensionSize);
-
- const int size = Common::strlcat(buf, _languageExtension[lang], bufSize);
- if (size >= bufSize) {
- warning("buffer too small to append language extension");
- return 0;
- }
-
- return buf;
-}
-
int KyraEngine_MR::loadLanguageFile(const char *file, uint8 *&buffer) {
delete[] buffer;
buffer = 0;
uint32 size = 0;
- char nBuf[32];
- Common::strlcpy(nBuf, file, sizeof(nBuf));
- buffer = _res->fileData(appendLanguage(nBuf, _lang, sizeof(nBuf)), &size);
+ Common::String nBuf = file;
+ nBuf += _languageExtension[_lang];
+ buffer = _res->fileData(nBuf.c_str(), &size);
return buffer ? size : 0;
}
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 0d9d66ce95..b762648d29 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -662,8 +662,6 @@ private:
static const char *_languageExtension[];
static const int _languageExtensionSize;
- char *appendLanguage(char *buf, int lang, int bufSize);
-
int loadLanguageFile(const char *file, uint8 *&buffer);
};
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index f79fabf9eb..3d81368d2d 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -56,7 +56,6 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
_gameToLoad = -1;
_mouseState = -1;
- _updateHandItemCursor = false;
_deathHandler = -1;
memset(_flagsTable, 0, sizeof(_flagsTable));
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index cf15b189ac..83455f3922 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -73,33 +73,27 @@ class KyraMetaEngine;
* Kyrandia 2 Russian (no feature request)
* Kyrandia 3 Russian (feature request #2812792 "Kyrandia3 Russian")
*
- * The primary maintainer for the engine is LordHoto, although some parts are maintained by _athrxx.
- * If you have questions about parts of the code, the following rough description might help in
- * determining who you should ask:
- * _athrxx is the maintainer for the Lands of Lore subengine, he also maintains most of the FM-TOWNS
- * and PC98 specific code (especially the sound code, also some ingame code) and the Kyrandia 2
- * sequence player code.
- * LordHoto is responsible for the rest of the codebase, he also worked on the graphics output for 16
- * color PC98 games.
+ * The engine is maintained by _athrxx.
*
* Other people who worked on this engine include cyx, who initially started to work on Kyrandia 1
* support, vinterstum, who did various things for Kyrandia 1 and started to work on the Kyrandia 2
* sequence player code and also on the TIM script code, and eriktorbjorn, who helped out naming
* our AdLib player code and also contributed a work around for a music bug in the "Pool of Sorrow"
- * scene of Kyrandia 1, which is also present in the original. All three mentioned developers are
- * not actively working on KYRA anymore.
+ * scene of Kyrandia 1, which is also present in the original. LordHoto worked on Kyrandia 1 to 3
+ * support and graphics output for 16 color PC98 games and was a maintainer of the Kyrandia part.
+ * All mentioned developers are not actively working on KYRA anymore.
*
* The engine is mostly finished code wise. A possible remaining task is proper refactoring,
* which might help in reducing binary size and along with it runtime memory use, but of course
* might lead to regressions (since the current code makes no problems on our low end ports, it
* is pretty minor priority though, since the benefit would be mostly nicer code). The biggest
- * task left is the kyra.dat handling, which is currently being revised by LordHoto.
+ * task left is the kyra.dat handling.
*
* Games using this engine:
* - The Legend of Kyrandia (fully supported, except for Macintosh port, which lacks sound)
* - (The) Hand of Fate (fully supported)
* - Malcolm's Revenge (fully supported)
- * - Lands of Lore: The Throne of Chaos (completable, still work in progress)
+ * - Lands of Lore: The Throne of Chaos (fully supported)
*/
namespace Kyra {
@@ -343,9 +337,6 @@ protected:
virtual void setHandItem(Item item) = 0;
virtual void removeHandItem() = 0;
- void setDelayedCursorUpdate() { _updateHandItemCursor = true; }
- bool _updateHandItemCursor;
-
// game flags
uint8 _flagsTable[100]; // TODO: check this value
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 3a8a332840..2cca4fd4e3 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -43,7 +43,12 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_txt = 0;
_tim = 0;
- switch (_flags.lang) {
+ _lang = 0;
+ Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
+ if (lang == _flags.fanLang && _flags.replacedLang != Common::UNK_LANG)
+ lang = _flags.replacedLang;
+
+ switch (lang) {
case Common::EN_ANY:
case Common::EN_USA:
case Common::EN_GRB:
@@ -611,11 +616,11 @@ void LoLEngine::preInit() {
loadTalkFile(0);
- char filename[32];
- snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);
- _res->exists(filename, true);
+ Common::String filename;
+ filename = Common::String::format("LANDS.%s", _languageExt[_lang]);
+ _res->exists(filename.c_str(), true);
delete[] _landsFile;
- _landsFile = _res->fileData(filename, 0);
+ _landsFile = _res->fileData(filename.c_str(), 0);
loadItemIconShapes();
}
@@ -930,14 +935,6 @@ void LoLEngine::runLoop() {
checkFloatingPointerRegions();
gui_updateInput();
- if (_updateHandItemCursor) {
- // This works around an issue which would occur when setHandItem(_itemInHand)
- // was called from inside loadGameState(). When loading via GMM the
- // mouse cursor would not be set correctly.
- _updateHandItemCursor = false;
- setHandItem(_itemInHand);
- }
-
update();
if (_sceneUpdateRequired)
@@ -1161,9 +1158,8 @@ void LoLEngine::loadCharFaceShapes(int charNum, int id) {
if (id < 0)
id = -id;
- char file[13];
- snprintf(file, sizeof(file), "FACE%02d.SHP", id);
- _screen->loadBitmap(file, 3, 3, 0);
+ Common::String file = Common::String::format("FACE%02d.SHP", id);
+ _screen->loadBitmap(file.c_str(), 3, 3, 0);
const uint8 *p = _screen->getCPagePtr(3);
for (int i = 0; i < 40; i++) {
@@ -1819,21 +1815,16 @@ void LoLEngine::updateSequenceBackgroundAnimations() {
}
void LoLEngine::loadTalkFile(int index) {
- char file[8];
-
if (index == _curTlkFile)
return;
- if (_curTlkFile > 0 && index > 0) {
- snprintf(file, sizeof(file), "%02d.TLK", _curTlkFile);
- _res->unloadPakFile(file);
- }
+ if (_curTlkFile > 0 && index > 0)
+ _res->unloadPakFile(Common::String::format("%02d.TLK", _curTlkFile));
if (index > 0)
_curTlkFile = index;
- snprintf(file, sizeof(file), "%02d.TLK", index);
- _res->loadPakFile(file);
+ _res->loadPakFile(Common::String::format("%02d.TLK", index));
}
int LoLEngine::characterSays(int track, int charId, bool redraw) {
@@ -2702,12 +2693,11 @@ int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
snd_playSoundEffect(155, -1);
- char wsafile[13];
- snprintf(wsafile, 13, "mists%0d.wsa", spellLevel + 1);
+ Common::String wsafile = Common::String::format("mists%0d.wsa", spellLevel + 1);
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- mov->open(wsafile, 1, 0);
+ mov->open(wsafile.c_str(), 1, 0);
if (!mov->opened())
- error("Mist: Unable to load mists.wsa");
+ error("Mist: Unable to load %s", wsafile.c_str());
snd_playSoundEffect(_mistAnimData[spellLevel].sound, -1);
playSpellAnimation(mov, _mistAnimData[spellLevel].part1First, _mistAnimData[spellLevel].part1Last, 7, 112, 0, 0, 0, 0, 0, false);
@@ -2734,12 +2724,11 @@ int LoLEngine::processMagicLightning(int charNum, int spellLevel) {
_lightningDiv = _lightningProps[spellLevel].frameDiv;
_lightningFirstSfx = 0;
- char wsafile[13];
- snprintf(wsafile, 13, "litning%d.wsa", spellLevel + 1);
+ Common::String wsafile = Common::String::format("litning%d.wsa", spellLevel + 1);
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- mov->open(wsafile, 1, 0);
+ mov->open(wsafile.c_str(), 1, 0);
if (!mov->opened())
- error("Litning: Unable to load litning.wsa");
+ error("Litning: Unable to load %s", wsafile.c_str());
for (int i = 0; i < 4; i++)
playSpellAnimation(mov, 0, _lightningProps[spellLevel].lastFrame, 3, 93, 0, &LoLEngine::callbackProcessMagicLightning, 0, 0, 0, false);
@@ -3139,11 +3128,10 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
int vX = _updateSpellBookCoords[slot << 1] + 32;
int vY = _updateSpellBookCoords[(slot << 1) + 1] + 5;
- char wsaFile[13];
+ Common::String wsaFile = Common::String::format("write%0d", spell);
if (_flags.isTalkie)
- snprintf(wsaFile, 13, "write%0d%c.wsa", spell, (_lang == 1) ? 'f' : (_lang == 0 ? 'e' : 'g'));
- else
- snprintf(wsaFile, 13, "write%0d.wsa", spell);
+ wsaFile += (_lang == 1) ? 'f' : (_lang == 0 ? 'e' : 'g');
+ wsaFile += ".wsa";
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
snd_playSoundEffect(95, -1);
@@ -3187,7 +3175,7 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
playSpellAnimation(mov, 0, 6, 5, _updateSpellBookCoords[slot << 1], _updateSpellBookCoords[(slot << 1) + 1], 0, 0, 0, 0, false);
mov->close();
- mov->open(wsaFile, 0, 0);
+ mov->open(wsaFile.c_str(), 0, 0);
if (!mov->opened())
error("SpellBook: Unable to load spellbook anim");
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
@@ -4160,10 +4148,9 @@ void LoLEngine::loadMapLegendData(int level) {
legendData[i * 6 + 5] = 0xffff;
}
- char file[13];
+ Common::String file = Common::String::format("level%d.xxx", level);
uint32 size = 0;
- snprintf(file, 12, "level%d.xxx", level);
- uint8 *data = _res->fileData(file, &size);
+ uint8 *data = _res->fileData(file.c_str(), &size);
uint8 *pos = data;
size = MIN<uint32>(size / 12, 32);
@@ -4531,10 +4518,9 @@ void LoLEngine::generateTempData() {
_lvlTempData[l]->monsters = new MonsterInPlay[30];
_lvlTempData[l]->flyingObjects = new FlyingObject[8];
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", _currentLevel);
+ Common::String filename = Common::String::format("LEVEL%d.CMZ", _currentLevel);
- _screen->loadBitmap(filename, 15, 15, 0);
+ _screen->loadBitmap(filename.c_str(), 15, 15, 0);
const uint8 *p = _screen->getCPagePtr(14);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 943bb7f8d5..06a4f29f63 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -717,7 +717,7 @@ private:
int olol_setScriptTimer(EMCState *script);
int olol_createHandItem(EMCState *script);
int olol_playAttackSound(EMCState *script);
- int olol_characterJoinsParty(EMCState *script);
+ int olol_addRemoveCharacter(EMCState *script);
int olol_giveItem(EMCState *script);
int olol_loadTimScript(EMCState *script);
int olol_runTimScript(EMCState *script);
diff --git a/engines/kyra/saveload_hof.cpp b/engines/kyra/saveload_hof.cpp
index b395a38acd..645bd2903f 100644
--- a/engines/kyra/saveload_hof.cpp
+++ b/engines/kyra/saveload_hof.cpp
@@ -306,7 +306,7 @@ Common::Error KyraEngine_HoF::loadGameState(int slot) {
_mainCharacter.facing = 4;
enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1);
- setDelayedCursorUpdate();
+ setHandItem(_itemInHand);
if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1)
snd_playWanderScoreViaMap(_lastMusicCommand, 1);
diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp
index 7689a904b0..34762d4c92 100644
--- a/engines/kyra/saveload_lok.cpp
+++ b/engines/kyra/saveload_lok.cpp
@@ -170,7 +170,7 @@ Common::Error KyraEngine_LoK::loadGameState(int slot) {
_screen->copyRegion(8, 8, 8, 8, 304, 212, 10, 0);
}
- setDelayedCursorUpdate();
+ setHandItem(_itemInHand);
// Will-O-Wisp uses a different shape size than Brandon's usual
// shape, thus we need to setup the correct size depending on
diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp
index c81ace26f0..07842ea358 100644
--- a/engines/kyra/saveload_lol.cpp
+++ b/engines/kyra/saveload_lol.cpp
@@ -257,7 +257,7 @@ Common::Error LoLEngine::loadGameState(int slot) {
int t = _credits;
_credits = 0;
giveCredits(t, 0);
- setDelayedCursorUpdate();
+ setHandItem(_itemInHand);
loadLevel(_currentLevel);
gui_drawPlayField();
timerSpecialCharacterUpdate(0);
diff --git a/engines/kyra/saveload_mr.cpp b/engines/kyra/saveload_mr.cpp
index 0fd3e520f9..139375264f 100644
--- a/engines/kyra/saveload_mr.cpp
+++ b/engines/kyra/saveload_mr.cpp
@@ -305,7 +305,7 @@ Common::Error KyraEngine_MR::loadGameState(int slot) {
_goodConsciencePosition = false;
enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1);
- setDelayedCursorUpdate();
+ setHandItem(_itemInHand);
if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1)
snd_playWanderScoreViaMap(_lastMusicCommand, 1);
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index 305036fc51..165919dff2 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -67,18 +67,17 @@ void LoLEngine::loadLevel(int index) {
loadLevelWallData(index, true);
_loadLevelFlag = 1;
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.INI", index);
+ Common::String filename = Common::String::format("LEVEL%d.INI", index);
int f = _hasTempDataFlags & (1 << (index - 1));
- runInitScript(filename, f ? 0 : 1);
+ runInitScript(filename.c_str(), f ? 0 : 1);
if (f)
restoreBlockTempData(index);
- snprintf(filename, sizeof(filename), "LEVEL%d.INF", index);
- runInfScript(filename);
+ filename = Common::String::format("LEVEL%d.INF", index);
+ runInfScript(filename.c_str());
addLevelItems();
deleteMonstersFromBlock(_currentBlock);
@@ -142,11 +141,10 @@ void LoLEngine::assignBlockObject(LevelBlockProperty *l, uint16 item) {
}
void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.WLL", index);
+ Common::String filename = Common::String::format("LEVEL%d.WLL", index);
uint32 size;
- uint8 *file = _res->fileData(filename, &size);
+ uint8 *file = _res->fileData(filename.c_str(), &size);
uint16 c = READ_LE_UINT16(file);
loadLevelShpDat(_levelShpList[c], _levelDatList[c], false);
@@ -241,10 +239,9 @@ void LoLEngine::restoreBlockTempData(int index) {
memcpy(_monsters, _lvlTempData[l]->monsters, sizeof(MonsterInPlay) * 30);
memcpy(_flyingObjects, _lvlTempData[l]->flyingObjects, sizeof(FlyingObject) * 8);
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", index);
+ Common::String filename = Common::String::format("LEVEL%d.CMZ", index);
- _screen->loadBitmap(filename, 3, 3, 0);
+ _screen->loadBitmap(filename.c_str(), 3, 3, 0);
const uint8 *p = _screen->getCPagePtr(2);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;
@@ -366,13 +363,13 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
_lastSpecialColor = 0x44;
}
- char fname[13];
+ Common::String fname;
const uint8 *v = 0;
int tlen = 0;
if (_flags.use16ColorMode) {
- snprintf(fname, sizeof(fname), "%s.VCF", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VCF", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
tlen = READ_LE_UINT16(v) << 5;
v += 2;
@@ -383,8 +380,8 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
memcpy(_vcfBlocks, v, tlen);
}
- snprintf(fname, sizeof(fname), "%s.VCN", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VCN", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
tlen = READ_LE_UINT16(v);
v += 2;
@@ -434,8 +431,8 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
memcpy(_vcnBlocks, v, vcnLen);
v += vcnLen;
- snprintf(fname, sizeof(fname), "%s.VMP", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VMP", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
if (vmpLen == -1)
@@ -503,9 +500,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
generateBrightnessPalette(_screen->getPalette(0), _screen->getPalette(1), _brightness, _lampEffect);
if (_flags.isTalkie) {
- char tname[13];
- snprintf(tname, sizeof(tname), "LEVEL%.02d.TLC", _currentLevel);
- Common::SeekableReadStream *s = _res->createReadStream(tname);
+ Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("LEVEL%.02d.TLC", _currentLevel));
s->read(_transparencyTable1, 256);
s->read(_transparencyTable2, 5120);
delete s;
@@ -1375,9 +1370,8 @@ void LoLEngine::processGasExplosion(int soundId) {
if (dist) {
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- char file[13];
- snprintf(file, 13, "gasexp%0d.wsa", dist);
- mov->open(file, 1, 0);
+ Common::String file = Common::String::format("gasexp%0d.wsa", dist);
+ mov->open(file.c_str(), 1, 0);
if (!mov->opened())
error("Gas: Unable to load gasexp.wsa");
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index a875e67a68..1afefcffa4 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -1088,33 +1088,27 @@ int LoLEngine::olol_playAttackSound(EMCState *script) {
return 1;
}
-int LoLEngine::olol_characterJoinsParty(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_characterJoinsParty(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+int LoLEngine::olol_addRemoveCharacter(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_addRemoveCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
int16 id = stackPos(0);
- if (id < 0)
+ if (id < 0) {
id = -id;
+ for (int i = 0; i < 4; i++) {
+ if (!(_characters[i].flags & 1) || _characters[i].id != id)
+ continue;
- for (int i = 0; i < 4; i++) {
- if (!(_characters[i].flags & 1) || _characters[i].id != id)
- continue;
-
- _characters[i].flags &= 0xfffe;
- calcCharPortraitXpos();
+ _characters[i].flags &= 0xfffe;
+ calcCharPortraitXpos();
- if (!_updateFlags) {
- gui_enableDefaultPlayfieldButtons();
- gui_drawPlayField();
+ if (_selectedCharacter == i)
+ _selectedCharacter = 0;
+ break;
}
-
- if (_selectedCharacter == i)
- _selectedCharacter = 0;
-
- return 1;
+ } else {
+ addCharacter(id);
}
- addCharacter(id);
-
if (!_updateFlags) {
gui_enableDefaultPlayfieldButtons();
gui_drawPlayField();
@@ -1136,9 +1130,8 @@ int LoLEngine::olol_loadTimScript(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadTimScript(%p) (%d, %s)", (const void *)script, stackPos(0), stackPosString(1));
if (_activeTim[stackPos(0)])
return 1;
- char file[13];
- snprintf(file, sizeof(file), "%s.TIM", stackPosString(1));
- _activeTim[stackPos(0)] = _tim->load(file, &_timIngameOpcodes);
+ Common::String file = Common::String::format("%s.TIM", stackPosString(1));
+ _activeTim[stackPos(0)] = _tim->load(file.c_str(), &_timIngameOpcodes);
return 1;
}
@@ -1185,10 +1178,9 @@ int LoLEngine::olol_giveItemToMonster(EMCState *script) {
int LoLEngine::olol_loadLangFile(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLangFile(%p) (%s)", (const void *)script, stackPosString(0));
- char filename[13];
- snprintf(filename, sizeof(filename), "%s.%s", stackPosString(0), _languageExt[_lang]);
+ Common::String filename = Common::String::format("%s.%s", stackPosString(0), _languageExt[_lang]);
delete[] _levelLangFile;
- _levelLangFile = _res->fileData(filename, 0);
+ _levelLangFile = _res->fileData(filename.c_str(), 0);
return 1;
}
@@ -2825,7 +2817,7 @@ void LoLEngine::setupOpcodeTable() {
Opcode(olol_setScriptTimer);
Opcode(olol_createHandItem);
Opcode(olol_playAttackSound);
- Opcode(olol_characterJoinsParty);
+ Opcode(olol_addRemoveCharacter);
// 0x4C
Opcode(olol_giveItem);
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index 501ae2defd..6f0f0ab083 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -482,17 +482,16 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
wsaOpenFlags = 1;
}
- char file[32];
- snprintf(file, 32, "%s.WSA", filename);
+ Common::String file = Common::String::format("%s.WSA", filename);
- if (_vm->resource()->exists(file)) {
+ if (_vm->resource()->exists(file.c_str())) {
if (isLoLDemo)
wsa = new WSAMovie_v1(_vm);
else
wsa = new WSAMovie_v2(_vm);
assert(wsa);
- wsa->open(file, wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
+ wsa->open(file.c_str(), wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
}
if (wsa && wsa->opened()) {
@@ -526,10 +525,10 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
}
if (wsaFlags & 4) {
- snprintf(file, 32, "%s.CPS", filename);
+ file = Common::String::format("%s.CPS", filename);
- if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
+ if (_vm->resource()->exists(file.c_str())) {
+ _screen->loadBitmap(file.c_str(), 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
@@ -550,10 +549,10 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
_screen->updateScreen();
}
- snprintf(file, 32, "%s.CPS", filename);
+ file = Common::String::format("%s.CPS", filename);
- if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
+ if (_vm->resource()->exists(file.c_str())) {
+ _screen->loadBitmap(file.c_str(), 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
@@ -922,13 +921,12 @@ int TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, i
if (wsaFlags & 8)
wsaOpenFlags |= 1;
- char file[32];
- snprintf(file, 32, "%s.WSA", filename);
+ Common::String file = Common::String::format("%s.WSA", filename);
- if (_vm->resource()->exists(file)) {
+ if (_vm->resource()->exists(file.c_str())) {
wsa = new WSAMovie_v2(_vm);
assert(wsa);
- wsa->open(file, wsaOpenFlags, &_screen->getPalette(3));
+ wsa->open(file.c_str(), wsaOpenFlags, &_screen->getPalette(3));
}
if (!_vm->_flags.use16ColorMode) {
diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp
index 9a47016f2b..27f3951faf 100644
--- a/engines/kyra/sequences_lol.cpp
+++ b/engines/kyra/sequences_lol.cpp
@@ -202,7 +202,7 @@ void LoLEngine::setupPrologueData(bool load) {
void LoLEngine::showIntro() {
_tim = new TIMInterpreter(this, _screen, _system);
assert(_tim);
-
+
if (_flags.platform == Common::kPlatformPC98)
showStarcraftLogo();
@@ -306,9 +306,8 @@ int LoLEngine::chooseCharacter() {
Screen::FontId old = _screen->setFont(Screen::FID_SJIS_FNT);
for (int j = 0; j < 3; ++j) {
- char buffer[3];
- snprintf(buffer, sizeof(buffer), "%2d", _charPreviews[i].attrib[j]);
- _screen->printText(buffer, _charPosXPC98[i] + 16, 176 + j * 8, 0x81, 0x00);
+ Common::String attribString = Common::String::format("%2d", _charPreviews[i].attrib[j]);
+ _screen->printText(attribString.c_str(), _charPosXPC98[i] + 16, 176 + j * 8, 0x81, 0x00);
}
_screen->setFont(old);
}
@@ -1116,7 +1115,7 @@ void LoLEngine::showOutro(int character, bool maxDifficulty) {
showCredits();
_eventList.clear();
-
+
if (!shouldQuit()) {
switch (character) {
case 0:
diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h
index 2ba0890789..be3c09de96 100644
--- a/engines/kyra/sound_intern.h
+++ b/engines/kyra/sound_intern.h
@@ -140,7 +140,7 @@ private:
uint8 _sfxChannel;
TownsEuphonyDriver *_driver;
-
+
bool _cdaPlaying;
const uint8 *_musicFadeTable;
diff --git a/engines/kyra/sound_lok.cpp b/engines/kyra/sound_lok.cpp
index 95a632c08c..b2a9c2fd93 100644
--- a/engines/kyra/sound_lok.cpp
+++ b/engines/kyra/sound_lok.cpp
@@ -74,9 +74,8 @@ void KyraEngine_LoK::snd_playWanderScoreViaMap(int command, int restart) {
}
void KyraEngine_LoK::snd_playVoiceFile(int id) {
- char vocFile[9];
- snprintf(vocFile, sizeof(vocFile), "%03d", id);
- _speechPlayTime = _sound->voicePlay(vocFile, &_speechHandle);
+ Common::String vocFile = Common::String::format("%03d", id);
+ _speechPlayTime = _sound->voicePlay(vocFile.c_str(), &_speechHandle);
}
void KyraEngine_LoK::snd_voiceWaitForFinish(bool ingame) {
diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp
index a7776f0ab6..7262635728 100644
--- a/engines/kyra/sound_lol.cpp
+++ b/engines/kyra/sound_lol.cpp
@@ -50,36 +50,34 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {
_lastSpeaker = speaker;
_nextSpeechId = _nextSpeaker = -1;
- char pattern1[8];
- char pattern2[5];
- char file1[13];
- char file2[13];
- char file3[13];
- file3[0] = 0;
+ Common::String pattern1;
+ Common::String file1;
+ Common::String file2;
+ Common::String file3;
SpeechList newSpeechList;
- snprintf(pattern2, sizeof(pattern2), "%02d", id & 0x4000 ? 0 : _curTlkFile);
+ Common::String pattern2 = Common::String::format("%02d", id & 0x4000 ? 0 : _curTlkFile);
if (id & 0x4000) {
- snprintf(pattern1, sizeof(pattern1), "%03X", id & 0x3fff);
+ pattern1 = Common::String::format("%03X", id & 0x3fff);
} else if (id < 1000) {
- snprintf(pattern1, sizeof(pattern1), "%03d", id);
+ pattern1 = Common::String::format("%03d", id);
} else {
- snprintf(file3, sizeof(file3), "@%04d%c.%s", id - 1000, (char)speaker, pattern2);
- if (_sound->isVoicePresent(file3))
- newSpeechList.push_back(_sound->getVoiceStream(file3));
+ file3 = Common::String::format("@%04d%c.%s", id - 1000, (char)speaker, pattern2.c_str());
+ if (_sound->isVoicePresent(file3.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file3.c_str()));
}
- if (!file3[0]) {
+ if (file3.empty()) {
for (char i = 0; ; i++) {
char symbol = '0' + i;
- snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, symbol, pattern2);
- snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', symbol, pattern2);
- if (_sound->isVoicePresent(file1))
- newSpeechList.push_back(_sound->getVoiceStream(file1));
- else if (_sound->isVoicePresent(file2))
- newSpeechList.push_back(_sound->getVoiceStream(file2));
+ file1 = Common::String::format("%s%c%c.%s", pattern1.c_str(), (char)speaker, symbol, pattern2.c_str());
+ file2 = Common::String::format("%s%c%c.%s", pattern1.c_str(), '_', symbol, pattern2.c_str());
+ if (_sound->isVoicePresent(file1.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file1.c_str()));
+ else if (_sound->isVoicePresent(file2.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file2.c_str()));
else
break;
}
@@ -260,9 +258,7 @@ void LoLEngine::snd_loadSoundFile(int track) {
int t = (track - 250) * 3;
if (_curMusicFileIndex != _musicTrackMap[t] || _curMusicFileExt != (char)_musicTrackMap[t + 1]) {
snd_stopMusic();
- char filename[13];
- snprintf(filename, sizeof(filename), "LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]);
- _sound->loadSoundFile(filename);
+ _sound->loadSoundFile(Common::String::format("LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]));
_curMusicFileIndex = _musicTrackMap[t];
_curMusicFileExt = (char)_musicTrackMap[t + 1];
} else {
diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp
index 6c003d0a11..dc0f8c11ec 100644
--- a/engines/kyra/sound_midi.cpp
+++ b/engines/kyra/sound_midi.cpp
@@ -25,6 +25,7 @@
#include "common/system.h"
#include "common/config-manager.h"
+#include "common/translation.h"
#include "gui/message.h"
@@ -471,11 +472,11 @@ SoundMidiPC::SoundMidiPC(KyraEngine_v1 *vm, Audio::Mixer *mixer, MidiDriver *dri
// (This will only happen in The Legend of Kyrandia 1 though, all other
// supported games include special General MIDI tracks).
if (_type == kMidiMT32 && !_nativeMT32) {
- ::GUI::MessageDialog dialog("You appear to be using a General MIDI device,\n"
+ ::GUI::MessageDialog dialog(_("You appear to be using a General MIDI device,\n"
"but your game only supports Roland MT32 MIDI.\n"
"We try to map the Roland MT32 instruments to\n"
"General MIDI ones. After all it might happen\n"
- "that a few tracks will not be correctly played.");
+ "that a few tracks will not be correctly played."));
dialog.runModal();
}
}
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index 73d435f3e5..012f1f5d7d 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -107,11 +107,11 @@ void SoundTowns::haltTrack() {
g_system->getAudioCDManager()->stop();
g_system->getAudioCDManager()->updateCD();
_cdaPlaying = false;
-
+
for (int i = 0; i < 6; i++)
_driver->chanVolume(i, 0);
for (int i = 0x40; i < 0x46; i++)
- _driver->chanVolume(i, 0);
+ _driver->chanVolume(i, 0);
for (int i = 0; i < 32; i++)
_driver->configChan_enable(i, 0);
_driver->stopParser();
@@ -128,7 +128,7 @@ void SoundTowns::loadSoundFile(uint file) {
void SoundTowns::playSoundEffect(uint8 track) {
if (!_sfxEnabled || !_sfxFileData)
return;
-
+
if (track == 0 || track == 10) {
stopAllSoundEffects();
return;
@@ -258,13 +258,13 @@ void SoundTowns::beginFadeOut() {
uint16 fadeVolCur[12];
uint16 fadeVolStep[12];
-
+
for (int i = 0; i < 6; i++) {
fadeVolCur[i] = READ_LE_UINT16(&_musicFadeTable[(_lastTrack * 12 + i) * 2]);
fadeVolStep[i] = fadeVolCur[i] / 50;
fadeVolCur[i + 6] = READ_LE_UINT16(&_musicFadeTable[(_lastTrack * 12 + 6 + i) * 2]);
fadeVolStep[i + 6] = fadeVolCur[i + 6] / 30;
- }
+ }
for (int i = 0; i < 12; i++) {
for (int ii = 0; ii < 6; ii++)
@@ -344,7 +344,7 @@ void SoundTowns::playEuphonyTrack(uint32 offset, int loop) {
uint32 trackSize = READ_LE_UINT32(_musicTrackData + 2048);
uint8 startTick = _musicTrackData[2052];
-
+
_driver->setMusicTempo(_musicTrackData[2053]);
src = _musicTrackData + 2054;
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 499cc6f301..d56abc5d47 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -38,7 +38,7 @@
namespace Kyra {
-#define RESFILE_VERSION 73
+#define RESFILE_VERSION 74
namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp
index 393fa8d11f..4406f3ec41 100644
--- a/engines/kyra/text_hof.cpp
+++ b/engines/kyra/text_hof.cpp
@@ -436,15 +436,16 @@ void KyraEngine_HoF::updateDlgBuffer() {
_npcTalkChpIndex = _currentChapter;
_npcTalkDlgIndex = _mainCharacter.dlgIndex;
- char filename[13];
- snprintf(filename, 13, "CH%.02d-S%.02d.DLG", _currentChapter, _npcTalkDlgIndex);
+ Common::String filename = Common::String::format("CH%.02d-S%.02d.DL", _currentChapter, _npcTalkDlgIndex);
const char *suffix = _flags.isTalkie ? suffixTalkie : suffixTowns;
if (_flags.platform != Common::kPlatformPC || _flags.isTalkie)
- filename[11] = suffix[_lang];
+ filename += suffix[_lang];
+ else
+ filename += 'G';
delete[] _dlgBuffer;
- _dlgBuffer = _res->fileData(filename, 0);
+ _dlgBuffer = _res->fileData(filename.c_str(), 0);
}
void KyraEngine_HoF::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) {
diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp
index 2cb752fdb3..d690b70266 100644
--- a/engines/kyra/text_mr.cpp
+++ b/engines/kyra/text_mr.cpp
@@ -625,24 +625,20 @@ void KyraEngine_MR::malcolmSceneStartupChat() {
}
void KyraEngine_MR::updateDlgBuffer() {
- char dlgFile[16];
- char cnvFile[16];
-
if (_cnvFile)
_cnvFile->seek(0, SEEK_SET);
if (_curDlgIndex == _mainCharacter.dlgIndex && _curDlgChapter == _currentChapter && _curDlgLang == _lang)
return;
- snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _currentChapter, _mainCharacter.dlgIndex);
- appendLanguage(dlgFile, _lang, 16);
- snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex);
+ Common::String dlgFile = Common::String::format("CH%.02d-S%.02d.%s", _currentChapter, _mainCharacter.dlgIndex, _languageExtension[_lang]);
+ Common::String cnvFile = Common::String::format("CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex);
delete _cnvFile;
delete _dlgBuffer;
- _res->exists(cnvFile, true);
- _res->exists(dlgFile, true);
+ _res->exists(cnvFile.c_str(), true);
+ _res->exists(dlgFile.c_str(), true);
_cnvFile = _res->createReadStream(cnvFile);
_dlgBuffer = _res->createReadStream(dlgFile);
assert(_cnvFile);
diff --git a/engines/lastexpress/data/animation.cpp b/engines/lastexpress/data/animation.cpp
index 1cbf7672d1..28d30ec7d1 100644
--- a/engines/lastexpress/data/animation.cpp
+++ b/engines/lastexpress/data/animation.cpp
@@ -77,7 +77,7 @@ bool Animation::load(Common::SeekableReadStream *stream, int flag) {
// Check if there is enough data
if (_stream->size() - _stream->pos() < (signed)(numChunks * sizeof(Chunk))) {
- debugC(2, kLastExpressDebugGraphics, "NIS file seems to be corrupted!");
+ debugC(2, kLastExpressDebugGraphics, "NIS file seems to be corrupted");
return false;
}
@@ -101,10 +101,10 @@ bool Animation::load(Common::SeekableReadStream *stream, int flag) {
bool Animation::process() {
if (!_currentChunk)
- error("Animation::process - internal error: the current chunk iterator is invalid!");
+ error("[Animation::process] Current chunk iterator is invalid");
if (_stream == NULL || _chunks.size() == 0)
- error("Trying to show an animation before loading data");
+ error("[Animation::process] Trying to show an animation before loading data");
// TODO: - subtract the time paused by the GUI
// - Re-implement to be closer to the original engine
@@ -191,7 +191,7 @@ bool Animation::process() {
break;
default:
- error(" UNKNOWN chunk type=%x frame=%d size=%d", _currentChunk->type, _currentChunk->frame, _currentChunk->size);
+ error("[Animation::process] UNKNOWN chunk type=%x frame=%d size=%d", _currentChunk->type, _currentChunk->frame, _currentChunk->size);
break;
}
_currentChunk++;
@@ -206,7 +206,7 @@ bool Animation::hasEnded() {
Common::Rect Animation::draw(Graphics::Surface *surface) {
if (!_overlay)
- error("Animation::draw - internal error: the current overlay animation frame is invalid!");
+ error("[Animation::draw] Current overlay animation frame is invalid");
// Paint the background
if (_backgroundCurrent == 1 && _background1)
@@ -242,7 +242,7 @@ AnimFrame *Animation::processChunkFrame(Common::SeekableReadStream *in, const Ch
void Animation::processChunkAudio(Common::SeekableReadStream *in, const Chunk &c) {
if (!_audio)
- error("Animation::processChunkAudio - internal error: the audio stream is invalid!");
+ error("[Animation::processChunkAudio] Audio stream is invalid");
// Skip the Snd header, to queue just the audio blocks
uint32 size = c.size;
diff --git a/engines/lastexpress/data/background.cpp b/engines/lastexpress/data/background.cpp
index de6fd7eeae..3d866c26f9 100644
--- a/engines/lastexpress/data/background.cpp
+++ b/engines/lastexpress/data/background.cpp
@@ -85,7 +85,7 @@ bool Background::load(Common::SeekableReadStream *stream) {
Common::Rect Background::draw(Graphics::Surface *surface) {
if (!_data) {
- debugC(2, kLastExpressDebugGraphics, "Trying to show a background before loading data!");
+ debugC(2, kLastExpressDebugGraphics, "Trying to show a background before loading data");
return Common::Rect();
}
diff --git a/engines/lastexpress/data/font.cpp b/engines/lastexpress/data/font.cpp
index 9a60b88a25..79cf64e617 100644
--- a/engines/lastexpress/data/font.cpp
+++ b/engines/lastexpress/data/font.cpp
@@ -89,17 +89,17 @@ bool Font::load(Common::SeekableReadStream *stream) {
uint16 Font::getCharGlyph(uint16 c) const {
//warning("%c", c);
if (c >= 0x200)
- error("Express::Font: Invalid character %d", c);
+ error("[Font::getCharGlyph] Invalid character %d", c);
return _charMap[c];
}
byte *Font::getGlyphImg(uint16 g) {
if (!_glyphs)
- error("Express::getGlyphImg: Invalid glyphs!");
+ error("[Font::getGlyphImg] Invalid glyphs");
if (g >= _numGlyphs)
- error("Express::getGlyphImg: Invalid glyph %d (%d available)", g, _numGlyphs);
+ error("[Font::getGlyphImg] Invalid glyph %d (%d available)", g, _numGlyphs);
return _glyphs + g * 18 * 8;
}
@@ -140,7 +140,7 @@ uint8 Font::getCharWidth(uint16 c) const{
return 10;
} else {
if (!_glyphWidths)
- error("Express::getCharWidth: Invalid glyphs widths!");
+ error("[Font::getCharWidth] Invalid glyphs widths");
return _glyphWidths[getCharGlyph(c)];
}
diff --git a/engines/lastexpress/data/scene.cpp b/engines/lastexpress/data/scene.cpp
index 2ec8e6935d..8f279ffbb3 100644
--- a/engines/lastexpress/data/scene.cpp
+++ b/engines/lastexpress/data/scene.cpp
@@ -187,10 +187,10 @@ bool Scene::checkHotSpot(const Common::Point &coord, SceneHotspot **hotspot) {
SceneHotspot *Scene::getHotspot(uint index) {
if (_hotspots.empty())
- error("Scene::getHotspot: scene does not have any hotspots!");
+ error("[Scene::getHotspot] Scene does not have any hotspots");
if (index >= _hotspots.size())
- error("Scene::getHotspot: invalid index (was: %d, max: %d)", index, _hotspots.size() - 1);
+ error("[Scene::getHotspot] Invalid index (was: %d, max: %d)", index, _hotspots.size() - 1);
return _hotspots[index];
}
@@ -202,7 +202,7 @@ Common::Rect Scene::draw(Graphics::Surface *surface) {
Common::String sceneName(_name);
sceneName.trim();
if (sceneName.empty())
- error("Scene::draw: This scene is not a valid drawing scene!");
+ error("[Scene::draw] This scene is not a valid drawing scene");
// Load background
Background *background = ((LastExpressEngine *)g_engine)->getResourceManager()->loadBackground(sceneName);
@@ -260,7 +260,7 @@ bool SceneLoader::load(Common::SeekableReadStream *stream) {
// Read the default scene to get the total number of scenes
Scene *header = Scene::load(_stream);
if (!header)
- error("SceneLoader::load: Invalid data file!");
+ error("[SceneLoader::load] Invalid data file");
debugC(2, kLastExpressDebugScenes, " found %d entries", header->entityPosition); /* Header entityPosition is the scene count */
diff --git a/engines/lastexpress/data/sequence.cpp b/engines/lastexpress/data/sequence.cpp
index a27c27de2e..a62348f6c0 100644
--- a/engines/lastexpress/data/sequence.cpp
+++ b/engines/lastexpress/data/sequence.cpp
@@ -115,7 +115,7 @@ AnimFrame::AnimFrame(Common::SeekableReadStream *in, const FrameInfo &f) : _pale
decompFF(in, f);
break;
default:
- error("Unknown frame compression: %d", f.compressionType);
+ error("[AnimFrame::AnimFrame] Unknown frame compression: %d", f.compressionType);
}
readPalette(in, f);
@@ -379,11 +379,11 @@ bool Sequence::load(Common::SeekableReadStream *stream, byte field30) {
// Move stream to start of frame
_stream->seek((int32)(_sequenceHeaderSize + i * _sequenceFrameSize), SEEK_SET);
if (_stream->eos())
- error("Couldn't seek to the current frame data");
+ error("[Sequence::load] Couldn't seek to the current frame data");
// Check if there is enough data
if ((unsigned)(_stream->size() - _stream->pos()) < _sequenceFrameSize)
- error("The sequence frame does not have a valid header");
+ error("[Sequence::load] The sequence frame does not have a valid header");
FrameInfo info;
info.read(_stream, true);
@@ -397,10 +397,10 @@ bool Sequence::load(Common::SeekableReadStream *stream, byte field30) {
FrameInfo *Sequence::getFrameInfo(uint16 index) {
if (_frames.size() == 0)
- error("Trying to decode a sequence before loading its data");
+ error("[Sequence::getFrameInfo] Trying to decode a sequence before loading its data");
if (index > _frames.size() - 1)
- error("Invalid sequence frame requested: %d, max %d", index, _frames.size() - 1);
+ error("[Sequence::getFrameInfo] Invalid sequence frame requested: %d, max %d", index, _frames.size() - 1);
return &_frames[index];
}
@@ -463,14 +463,14 @@ bool SequenceFrame::nextFrame() {
FrameInfo *SequenceFrame::getInfo() {
if (!_sequence)
- error("SequenceFrame::getFrameInfo: Invalid sequence!");
+ error("[SequenceFrame::getInfo] Invalid sequence");
return _sequence->getFrameInfo(_frame);
}
Common::String SequenceFrame::getName() {
if (!_sequence)
- error("SequenceFrame::getName: Invalid sequence!");
+ error("[SequenceFrame::getName] Invalid sequence");
return _sequence->getName();
}
diff --git a/engines/lastexpress/data/snd.cpp b/engines/lastexpress/data/snd.cpp
index 3ffe3ca14b..d92ebbc5e3 100644
--- a/engines/lastexpress/data/snd.cpp
+++ b/engines/lastexpress/data/snd.cpp
@@ -152,7 +152,7 @@ void AppendableSound::queueBuffer(const byte *data, uint32 size) {
void AppendableSound::queueBuffer(Common::SeekableReadStream *bufferIn) {
if (!_as)
- error("AppendableSound::queueBuffer - internal error: the audio stream is invalid!");
+ error("[AppendableSound::queueBuffer] Audio stream is invalid");
// Setup the ADPCM decoder
uint32 sizeIn = (uint32)bufferIn->size();
@@ -164,7 +164,7 @@ void AppendableSound::queueBuffer(Common::SeekableReadStream *bufferIn) {
void AppendableSound::finish() {
if (!_as)
- error("AppendableSound::queueBuffer - internal error: the audio stream is invalid!");
+ error("[AppendableSound::finish] Audio stream is invalid");
if (!_finished)
_as->finish();
diff --git a/engines/lastexpress/data/subtitle.cpp b/engines/lastexpress/data/subtitle.cpp
index c3a7397b66..0be832cbdd 100644
--- a/engines/lastexpress/data/subtitle.cpp
+++ b/engines/lastexpress/data/subtitle.cpp
@@ -168,13 +168,13 @@ bool SubtitleManager::load(Common::SeekableReadStream *stream) {
// Read header to get the number of subtitles
uint32 numSubtitles = stream->readUint16LE();
if (stream->eos())
- error("Cannot read from subtitle file");
+ error("[SubtitleManager::load] Cannot read from subtitle file");
debugC(3, kLastExpressDebugSubtitle, "Number of subtitles in file: %d", numSubtitles);
// TODO: Check that stream contain enough data
//if (stream->size() < (signed)(numSubtitles * sizeof(SubtitleData))) {
- //debugC(2, kLastExpressDebugSubtitle, "Subtitle file does not contain valid data!");
+ //debugC(2, kLastExpressDebugSubtitle, "Subtitle file does not contain valid data");
//return false;
//}
diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index 4b7c5f6a9a..dc2807db63 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -31,18 +31,21 @@
#include "lastexpress/data/snd.h"
#include "lastexpress/data/subtitle.h"
+#include "lastexpress/fight/fight.h"
+
#include "lastexpress/game/action.h"
#include "lastexpress/game/beetle.h"
-#include "lastexpress/game/fight.h"
#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savegame.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/graphics.h"
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -792,7 +795,7 @@ bool Debugger::cmdFight(int argc, const char **argv) {
restoreArchive();
// Stop audio and restore scene
- getSound()->stopAllSound();
+ getSoundQueue()->stopAllSound();
clearBg(GraphicsManager::kBackgroundAll);
@@ -924,7 +927,7 @@ bool Debugger::cmdBeetle(int argc, const char **argv) {
restoreArchive();
// Stop audio and restore scene
- getSound()->stopAllSound();
+ getSoundQueue()->stopAllSound();
clearBg(GraphicsManager::kBackgroundAll);
diff --git a/engines/lastexpress/detection.cpp b/engines/lastexpress/detection.cpp
index 7c7c6b0a36..0a177809dd 100644
--- a/engines/lastexpress/detection.cpp
+++ b/engines/lastexpress/detection.cpp
@@ -21,6 +21,7 @@
*/
#include "lastexpress/lastexpress.h"
+#include "engines/advancedDetector.h"
namespace LastExpress {
@@ -46,7 +47,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -64,7 +65,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -82,7 +83,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -97,7 +98,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformUnknown,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -115,7 +116,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -126,14 +127,14 @@ static const ADGameDescription gameDescriptions[] = {
"lastexpress",
"",
{
- {"HD.HPF", 0, "7cdd70fc0b1555785f1e9e8d371ea85c", 31301632}, // 1997-04-08 14:33:42
+ {"HD.HPF", 0, "7cdd70fc0b1555785f1e9e8d371ea85c", 31301632}, // 1997-04-08 14:33:42
{"CD1.HPF", 0, "6d74cc861d172466bc745ff8bf0e59c5", 522971136}, // 1997-04-08 13:05:56
{"CD2.HPF", 0, "b71ac9391de415807c74ff078f4fab22", 655702016}, // 1997-04-08 15:26:14
{"CD3.HPF", 0, "ee55d4310546dd2a38560b096d1c2771", 641144832}, // 1997-04-05 18:35:50
},
Common::DE_DEU,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -151,7 +152,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -162,49 +163,45 @@ static const ADGameDescription gameDescriptions[] = {
"lastexpress",
"",
{
- {"HD.HPF", 0, "5539e78fd7eecb70bc858e86b5709fe9", 29562880}, // 1997-12-11 14:11:52
+ {"HD.HPF", 0, "5539e78fd7eecb70bc858e86b5709fe9", 29562880}, // 1997-12-11 14:11:52
{"CD1.HPF", 0, "3c1c80b41f2c454b7b89dcb32648796c", 522328064}, // 1997-12-11 14:39:46
{"CD2.HPF", 0, "ea6414d5a718501cfd55de3884f4431d", 665411584}, // 1997-12-11 15:20:26
{"CD3.HPF", 0, "a5bd5b58acddbd951d4551f68de22025", 637718528}, // 1997-12-11 15:58:44
},
Common::IT_ITA,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
+ Common::GUIO_NONE
+ },
+
+ // The Last Express (Russian)
+ // expressw.exe 1999-04-05 15:33:56
+ // express.exe ???
+ {
+ "lastexpress",
+ "",
+ {
+ {"HD.HPF", 0, "a9e915c20f3231c5a1ac4455286971bb", 29908992}, // 1999-04-08 12:43:56
+ {"CD1.HPF", 0, "80fbb95c9228353436b7b38e4b5bb64d", 525805568}, // 1999-04-07 13:30:14
+ {"CD2.HPF", 0, "a1c8c344754e03eaa86eaabc6024709e", 677289984}, // 1999-04-07 16:19:56
+ {"CD3.HPF", 0, "ea5adac447e59ea6d4a1737abad46480", 642584576}, // 1999-04-07 17:26:18
+ },
+ Common::RU_RUS,
+ Common::kPlatformUnknown,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
AD_TABLE_END_MARKER
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- lastExpressGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "lastexpress",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class LastExpressMetaEngine : public AdvancedMetaEngine {
public:
- LastExpressMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ LastExpressMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), lastExpressGames) {
+ _singleid = "lastexpress";
+ _guioptions = Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX;
+ }
const char *getName() const {
return "Lastexpress";
@@ -224,6 +221,10 @@ bool LastExpressMetaEngine::createInstance(OSystem *syst, Engine **engine, const
return gd != 0;
}
+bool LastExpressEngine::isDemo() const {
+ return (bool)(_gameDescription->flags & ADGF_DEMO);
+}
+
} // End of namespace LastExpress
#if PLUGIN_ENABLED_DYNAMIC(LASTEXPRESS)
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
index 29bb31b248..c5c6f2a44d 100644
--- a/engines/lastexpress/entities/abbot.cpp
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -31,9 +31,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -1112,7 +1114,7 @@ IMPLEMENT_FUNCTION(35, Abbot, function35)
case 2:
getData()->location = kLocationOutsideCompartment;
- getSound()->playSound(kEntityAbbot, "Abb3040", SoundManager::kFlagInvalid, 45);
+ getSound()->playSound(kEntityAbbot, "Abb3040", kFlagInvalid, 45);
getEntities()->updatePositionEnter(kEntityAbbot, kCarRestaurant, 57);
setCallback(3);
@@ -1409,7 +1411,7 @@ IMPLEMENT_FUNCTION(43, Abbot, function43)
setup_playSound("Abb4002");
break;
} else {
- if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSound()->isBuffered(kEntityBoutarel) || !params->param4)
+ if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSoundQueue()->isBuffered(kEntityBoutarel) || !params->param4)
params->param4 = (uint)getState()->time + 450;
if (params->param4 < getState()->time) {
@@ -1754,7 +1756,7 @@ IMPLEMENT_FUNCTION(49, Abbot, pickBomb)
break;
case kActionKnock:
- if (!getSound()->isBuffered("LIB012", true))
+ if (!getSoundQueue()->isBuffered("LIB012", true))
getSound()->playSound(kEntityPlayer, "LIB012");
break;
diff --git a/engines/lastexpress/entities/alexei.cpp b/engines/lastexpress/entities/alexei.cpp
index d723a5607c..073ca3f175 100644
--- a/engines/lastexpress/entities/alexei.cpp
+++ b/engines/lastexpress/entities/alexei.cpp
@@ -29,9 +29,10 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/alouan.cpp b/engines/lastexpress/entities/alouan.cpp
index 715622aaab..cd79870559 100644
--- a/engines/lastexpress/entities/alouan.cpp
+++ b/engines/lastexpress/entities/alouan.cpp
@@ -26,9 +26,10 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp
index 0bedda41e8..b13aa21f6d 100644
--- a/engines/lastexpress/entities/anna.cpp
+++ b/engines/lastexpress/entities/anna.cpp
@@ -22,17 +22,20 @@
#include "lastexpress/entities/anna.h"
+#include "lastexpress/fight/fight.h"
+
#include "lastexpress/game/action.h"
#include "lastexpress/game/entities.h"
-#include "lastexpress/game/fight.h"
#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -311,7 +314,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
params->param4 = 0;
params->param5 = 0;
} else {
- getSound()->removeFromQueue(kEntityAnna);
+ getSoundQueue()->removeFromQueue(kEntityAnna);
getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
@@ -322,7 +325,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
break;
case kActionOpenDoor:
- getSound()->removeFromQueue(kEntityAnna);
+ getSoundQueue()->removeFromQueue(kEntityAnna);
setCallback(3);
setup_playSound("LIB013");
break;
@@ -338,8 +341,8 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
getEntities()->drawSequenceLeft(kEntityAnna, "418C");
- if (getSound()->isBuffered(kEntityAnna))
- getSound()->processEntry(kEntityAnna);
+ if (getSoundQueue()->isBuffered(kEntityAnna))
+ getSoundQueue()->processEntry(kEntityAnna);
getSound()->playSound(kEntityAnna, "ANN2135A");
break;
@@ -378,7 +381,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
break;
case 3:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
setCallback(4);
setup_playSound("MAX1120");
break;
@@ -502,7 +505,7 @@ IMPLEMENT_FUNCTION_IS(15, Anna, function15, TimeValue)
break;
case 1:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
setCallback(2);
setup_playSound("MAX1120");
break;
@@ -1455,7 +1458,7 @@ label_callback_1:
case 2:
case 3:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
setCallback(4);
setup_playSound("MAX1120");
break;
@@ -1520,8 +1523,8 @@ IMPLEMENT_FUNCTION(35, Anna, function35)
case kActionKnock:
case kActionOpenDoor:
- if (getSound()->isBuffered(kEntityAnna))
- getSound()->processEntry(kEntityAnna);
+ if (getSoundQueue()->isBuffered(kEntityAnna))
+ getSoundQueue()->processEntry(kEntityAnna);
if (savepoint.action == kActionKnock)
getSound()->playSound(kEntityPlayer, "LIB012");
@@ -1563,8 +1566,8 @@ IMPLEMENT_FUNCTION(35, Anna, function35)
break;
case kAction226031488:
- if (getSound()->isBuffered(kEntityAnna))
- getSound()->processEntry(kEntityAnna);
+ if (getSoundQueue()->isBuffered(kEntityAnna))
+ getSoundQueue()->processEntry(kEntityAnna);
getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
break;
@@ -1843,7 +1846,7 @@ IMPLEMENT_FUNCTION(41, Anna, function41)
case 1:
case 2:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
setCallback(3);
setup_playSound("MAX1120");
break;
@@ -2062,7 +2065,7 @@ IMPLEMENT_FUNCTION(47, Anna, function47)
break;
case 4:
- getSound()->playSound(kEntityAnna, getEvent(kEventAugustLunch) ? "Ann3136" : "Ann3136A", SoundManager::kFlagInvalid, 30);
+ getSound()->playSound(kEntityAnna, getEvent(kEventAugustLunch) ? "Ann3136" : "Ann3136A", kFlagInvalid, 30);
getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122358304);
setCallback(5);
@@ -2089,7 +2092,7 @@ IMPLEMENT_FUNCTION(48, Anna, function48)
break;
if (params->param3 != kTimeInvalid && getState()->time > kTime1969200) {
- UPDATE_PARAM_PROC_TIME(kTime1983600, (!getEntities()->isInRestaurant(kEntityPlayer) || getSound()->isBuffered(kEntityBoutarel)), params->param3, 150)
+ UPDATE_PARAM_PROC_TIME(kTime1983600, (!getEntities()->isInRestaurant(kEntityPlayer) || getSoundQueue()->isBuffered(kEntityBoutarel)), params->param3, 150)
setCallback(3);
setup_playSound("Aug3007A");
break;
@@ -2257,7 +2260,7 @@ IMPLEMENT_FUNCTION(51, Anna, function51)
break;
case kActionDefault:
- getSound()->playSound(kEntityAnna, "Aug3142", SoundManager::kFlagInvalid, 30);
+ getSound()->playSound(kEntityAnna, "Aug3142", kFlagInvalid, 30);
getEntities()->updatePositionEnter(kEntityAnna, kCarRestaurant, 57);
getEntities()->drawSequenceRight(kEntityAnna, "112A");
if (getEntities()->isInRestaurant(kEntityPlayer))
@@ -2480,7 +2483,7 @@ IMPLEMENT_FUNCTION(53, Anna, function53)
break;
case 1:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
setCallback(2);
setup_playSound("MAX1120");
break;
@@ -2619,7 +2622,7 @@ IMPLEMENT_FUNCTION(54, Anna, function54)
break;
case 1:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
setCallback(2);
setup_playSound("MAX1120");
break;
@@ -2788,7 +2791,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57)
break;
case 4:
- if (getSound()->isBuffered(kEntityAugust)) {
+ if (getSoundQueue()->isBuffered(kEntityAugust)) {
setCallback(4);
setup_updateFromTime(75);
} else {
@@ -2816,7 +2819,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57)
case kAction123712592:
getEntities()->drawSequenceLeft(kEntityAnna, "628Af");
- if (getSound()->isBuffered(kEntityAugust)) {
+ if (getSoundQueue()->isBuffered(kEntityAugust)) {
setCallback(4);
setup_updateFromTime(75);
} else {
@@ -3157,8 +3160,8 @@ IMPLEMENT_FUNCTION(63, Anna, function63)
// Anna will get killed...
case kAction272177921:
- if (getSound()->isBuffered("MUS012"))
- getSound()->processEntry("MUS012");
+ if (getSoundQueue()->isBuffered("MUS012"))
+ getSoundQueue()->processEntry("MUS012");
setCallback(1);
setup_savegame(kSavegameTypeEvent, kEventAnnaKilled);
@@ -3840,7 +3843,7 @@ IMPLEMENT_FUNCTION(78, Anna, function78)
case 2:
getAction()->playAnimation(kEventKronosHostageAnna);
getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
- getSound()->playSound(kEntityAnna, "Mus024", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityAnna, "Mus024", kFlagDefault);
setup_function79();
break;
}
@@ -3910,11 +3913,11 @@ IMPLEMENT_FUNCTION(80, Anna, function80)
case kActionNone:
UPDATE_PARAM(params->param1, getState()->timeTicks, 450);
- getSound()->playSound(kEntityPlayer, "Kro5001", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityPlayer, "Kro5001", kFlagDefault);
break;
case kActionEndSound:
- getSound()->playSound(kEntityPlayer, "Kro5002", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityPlayer, "Kro5002", kFlagDefault);
getState()->time = kTime4923000;
setCallback(1);
@@ -3934,12 +3937,12 @@ IMPLEMENT_FUNCTION(80, Anna, function80)
break;
case 1:
- if (getSound()->isBuffered(kEntityAnna))
- getSound()->processEntry(kEntityAnna);
+ if (getSoundQueue()->isBuffered(kEntityAnna))
+ getSoundQueue()->processEntry(kEntityAnna);
getAction()->playAnimation(kEventKronosBringFirebird);
getScenes()->loadSceneFromItem(kItemFirebird);
- getSound()->playSound(kEntityAnna, "Mus025", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityAnna, "Mus025", kFlagDefault);
break;
case 2:
@@ -3950,8 +3953,8 @@ IMPLEMENT_FUNCTION(80, Anna, function80)
case 3:
getProgress().isEggOpen = true;
- if (getSound()->isBuffered(kEntityAnna))
- getSound()->processEntry(kEntityAnna);
+ if (getSoundQueue()->isBuffered(kEntityAnna))
+ getSoundQueue()->processEntry(kEntityAnna);
getAction()->playAnimation(kEventKronosOpenFirebird);
getScenes()->loadSceneFromPosition(kCarRestaurant, 3);
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index f7e7390b90..eb3b09af59 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -33,9 +33,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -199,7 +201,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_S(13, August, playSound16)
- Entity::playSound(savepoint, false, SoundManager::kFlagDefault);
+ Entity::playSound(savepoint, false, kFlagDefault);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -338,7 +340,7 @@ IMPLEMENT_FUNCTION_II(19, August, function19, bool, bool)
case kAction1:
getData()->inventoryItem = kItemNone;
getSound()->playSound(kEntityPlayer, "CAT1002");
- getSound()->playSound(kEntityAugust, "AUG3101", SoundManager::kFlagInvalid, 15);
+ getSound()->playSound(kEntityAugust, "AUG3101", kFlagInvalid, 15);
break;
case kActionDefault:
@@ -1427,7 +1429,7 @@ IMPLEMENT_FUNCTION(29, August, function29)
if (getState()->time < kTime1134000) {
if (!getEntities()->isInRestaurant(kEntityPlayer)
- || getSound()->isBuffered("MRB1076") || getSound()->isBuffered("MRB1078") || getSound()->isBuffered("MRB1078A"))
+ || getSoundQueue()->isBuffered("MRB1076") || getSoundQueue()->isBuffered("MRB1078") || getSoundQueue()->isBuffered("MRB1078A"))
params->param3 = (uint)getState()->time + 225;
if (params->param3 > getState()->time)
@@ -1762,7 +1764,7 @@ IMPLEMENT_FUNCTION(34, August, function34)
break;
case kActionNone:
- if (!getSound()->isBuffered(kEntityAugust) && getProgress().field_18 != 4)
+ if (!getSoundQueue()->isBuffered(kEntityAugust) && getProgress().field_18 != 4)
getSound()->playSound(kEntityAugust, "AUG1057"); // August snoring
break;
@@ -2179,11 +2181,11 @@ IMPLEMENT_FUNCTION_III(42, August, function42, CarIndex, EntityPosition, bool)
getData()->inventoryItem = kItemNone;
getSound()->playSound(kEntityPlayer, "CAT1002");
- getSound()->playSound(kEntityAugust, getEvent(kEventAugustBringBriefcase) ? "AUG3103" : "AUG3100", SoundManager::kFlagInvalid, 15);
+ getSound()->playSound(kEntityAugust, getEvent(kEventAugustBringBriefcase) ? "AUG3103" : "AUG3100", kFlagInvalid, 15);
break;
case kActionExcuseMe:
- if (!getSound()->isBuffered(kEntityAugust))
+ if (!getSoundQueue()->isBuffered(kEntityAugust))
getSound()->excuseMe(kEntityAugust);
break;
@@ -2385,7 +2387,7 @@ IMPLEMENT_FUNCTION(45, August, function45)
case kAction1:
getData()->inventoryItem = kItemNone;
getSound()->playSound(kEntityPlayer, "CAT1002");
- getSound()->playSound(kEntityAugust, "AUG3102", SoundManager::kFlagInvalid, 15);
+ getSound()->playSound(kEntityAugust, "AUG3102", kFlagInvalid, 15);
break;
case kActionDefault:
@@ -3343,7 +3345,7 @@ IMPLEMENT_FUNCTION(65, August, function65)
getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
- if (!getSound()->isBuffered(kEntityAugust))
+ if (!getSoundQueue()->isBuffered(kEntityAugust))
getSound()->playSound(kEntityAugust, "AUG1057"); // August snoring
break;
}
@@ -3504,9 +3506,9 @@ IMPLEMENT_FUNCTION(69, August, unhookCars)
break;
case kActionDefault:
- getSound()->processEntries();
- if (getSound()->isBuffered("ARRIVE"))
- getSound()->removeFromQueue("ARRIVE");
+ getSoundQueue()->processEntries();
+ if (getSoundQueue()->isBuffered("ARRIVE"))
+ getSoundQueue()->removeFromQueue("ARRIVE");
setCallback(1);
setup_savegame(kSavegameTypeEvent, kEventAugustUnhookCarsBetrayal);
@@ -3516,7 +3518,7 @@ IMPLEMENT_FUNCTION(69, August, unhookCars)
if (getCallback() == 1) {
getAction()->playAnimation(getProgress().field_C ? kEventAugustUnhookCarsBetrayal : kEventAugustUnhookCars);
getEntities()->clearSequences(kEntityAugust);
- getSound()->resetState();
+ getSoundQueue()->resetState();
getSound()->playSound(kEntityPlayer, "MUS050");
getScenes()->loadSceneFromPosition(kCarRestaurant, 85, 1);
getSavePoints()->pushAll(kEntityAugust, kActionProceedChapter5);
diff --git a/engines/lastexpress/entities/boutarel.cpp b/engines/lastexpress/entities/boutarel.cpp
index 0b2040897c..315b12a69e 100644
--- a/engines/lastexpress/entities/boutarel.cpp
+++ b/engines/lastexpress/entities/boutarel.cpp
@@ -29,9 +29,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/scenes.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -214,7 +216,7 @@ IMPLEMENT_FUNCTION_I(11, Boutarel, function11, bool)
break;
case kChapter1:
- getSound()->playSound(kEntityBoutarel, "MRB1075", SoundManager::kFlagInvalid, 60);
+ getSound()->playSound(kEntityBoutarel, "MRB1075", kFlagInvalid, 60);
break;
case kChapter3:
@@ -941,7 +943,7 @@ IMPLEMENT_FUNCTION(29, Boutarel, function29)
if (getEntities()->isInRestaurant(kEntityAnna)
&& getEntities()->isInRestaurant(kEntityAugust)
- && !getSound()->isBuffered(kEntityBoutarel)
+ && !getSoundQueue()->isBuffered(kEntityBoutarel)
&& params->param3 != kTimeInvalid) {
if (getState()->time <= kTime1998000)
diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
index 1252a62d8d..96e08ba808 100644
--- a/engines/lastexpress/entities/chapters.cpp
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -57,13 +57,16 @@
#include "lastexpress/game/entities.h"
#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/menu/menu.h"
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/sound/queue.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
#include "lastexpress/resource.h"
@@ -159,20 +162,20 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
break;
case kActionEndSound:
- getSound()->playSound(kEntityChapters, "MUS0009", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityChapters, "MUS0009", kFlagDefault);
break;
case kActionKnock:
- if (!getSound()->isBuffered("LIB012", true))
+ if (!getSoundQueue()->isBuffered("LIB012", true))
getSound()->playSound(kEntityPlayer, "LIB012");
break;
case kActionOpenDoor:
if (params->param1) {
getEntities()->clearSequences(kEntityChapters);
- getSound()->processEntry(kEntityChapters);
+ getSoundQueue()->processEntry(kEntityChapters);
getSound()->playSound(kEntityPlayer, "LIB014");
- getSound()->resetState();
+ getSoundQueue()->resetState();
ENTITY_PARAM(0, 4) = 7;
@@ -191,10 +194,10 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
CALLBACK_ACTION();
} else {
getSound()->playSound(kEntityPlayer, "LIB014");
- getSound()->playSound(kEntityPlayer, "LIB015", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityPlayer, "LIB015", kFlagDefault, 15);
- if (!getSound()->isBuffered(kEntityChapters))
- getSound()->playSound(kEntityChapters, "MUS009", SoundManager::kFlagDefault);
+ if (!getSoundQueue()->isBuffered(kEntityChapters))
+ getSound()->playSound(kEntityChapters, "MUS009", kFlagDefault);
getScenes()->loadSceneFromPosition(kCarLocomotive, 38);
@@ -240,42 +243,42 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
RESET_ENTITY_STATE(kEntityHadija, Alouan, setup_function12);
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 3) = 0;
}
- getSound()->processEntries();
+ getSoundQueue()->processEntries();
- if (getSound()->isBuffered("CON1505"))
- getSound()->processEntry("CON1505");
+ if (getSoundQueue()->isBuffered("CON1505"))
+ getSoundQueue()->processEntry("CON1505");
- if (getSound()->isBuffered("AUG1057"))
- getSound()->processEntry("AUG1057");
+ if (getSoundQueue()->isBuffered("AUG1057"))
+ getSoundQueue()->processEntry("AUG1057");
- if (getSound()->isBuffered("ZFX1005"))
- getSound()->processEntry("ZFX1005");
+ if (getSoundQueue()->isBuffered("ZFX1005"))
+ getSoundQueue()->processEntry("ZFX1005");
- if (getSound()->isBuffered("ZFX1006"))
- getSound()->processEntry("ZFX1006");
+ if (getSoundQueue()->isBuffered("ZFX1006"))
+ getSoundQueue()->processEntry("ZFX1006");
- if (getSound()->isBuffered("ZFX1007"))
- getSound()->processEntry("ZFX1007");
+ if (getSoundQueue()->isBuffered("ZFX1007"))
+ getSoundQueue()->processEntry("ZFX1007");
- if (getSound()->isBuffered("ZFX1007A"))
- getSound()->processEntry("ZFX1007A");
+ if (getSoundQueue()->isBuffered("ZFX1007A"))
+ getSoundQueue()->processEntry("ZFX1007A");
- if (getSound()->isBuffered("ZFX1007B"))
- getSound()->processEntry("ZFX1007B");
+ if (getSoundQueue()->isBuffered("ZFX1007B"))
+ getSoundQueue()->processEntry("ZFX1007B");
- getSound()->playSound(kEntityPlayer, "MUS008", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
getInventory()->unselectItem();
// FIXME add event pump ?
- while (getSound()->isBuffered("MUS008"))
- getSound()->updateQueue();
+ while (getSoundQueue()->isBuffered("MUS008"))
+ getSoundQueue()->updateQueue();
getProgress().field_84 = true;
@@ -300,7 +303,7 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
if (params->param2 >= 3) {
- if (!getSound()->isBuffered("LIB031", true))
+ if (!getSoundQueue()->isBuffered("LIB031", true))
getSound()->playSound(kEntityPlayer, "LIB031");
if (params->param2 == 3) {
@@ -318,7 +321,7 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
return;
getProgress().chapter = kChapter1;
- getSound()->resetState();
+ getSoundQueue()->resetState();
getState()->time = kTimeChapter1;
getState()->timeDelta = 0;
@@ -384,7 +387,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
#define PLAY_STEAM() { \
- getSound()->resetState(); \
+ getSoundQueue()->resetState(); \
getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4)); \
ENTITY_PARAM(0, 2) = 0; \
}
@@ -562,7 +565,7 @@ label_chapter1_next:
}
if (ENTITY_PARAM(0, 3)) {
- getSound()->resetState();
+ getSoundQueue()->resetState();
ENTITY_PARAM(0, 3) = 0;
if (params->param4) {
@@ -693,16 +696,16 @@ IMPLEMENT_FUNCTION(9, Chapters, chapter1Next)
if (savepoint.action == kActionDefault) {
// Reset sound cache
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 3) = 0;
}
- getSound()->playSound(kEntityPlayer, "MUS008", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
getInventory()->unselectItem();
- while (getSound()->isBuffered("MUS008"))
- getSound()->updateQueue();
+ while (getSoundQueue()->isBuffered("MUS008"))
+ getSoundQueue()->updateQueue();
setup_chapter2();
}
@@ -789,7 +792,7 @@ IMPLEMENT_FUNCTION(11, Chapters, chapter2Init)
// Reset sound cache
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 3) = 0;
}
@@ -873,7 +876,7 @@ IMPLEMENT_FUNCTION(14, Chapters, chapter3Init)
getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 3) = 0;
}
@@ -914,11 +917,11 @@ IMPLEMENT_FUNCTION(15, Chapters, chapter3Handler)
break;
case 0:
- getSound()->playSound(kEntityPlayer, "ZFX1008", (SoundManager::FlagType)(rnd(15) + 2));
+ getSound()->playSound(kEntityPlayer, "ZFX1008", (SoundFlag)(rnd(15) + 2));
break;
case 1:
- getSound()->playSound(kEntityPlayer, "ZFX1009", (SoundManager::FlagType)(rnd(15) + 2));
+ getSound()->playSound(kEntityPlayer, "ZFX1009", (SoundFlag)(rnd(15) + 2));
break;
}
@@ -986,7 +989,7 @@ label_callback_8:
}
}
- getSound()->resetState();
+ getSoundQueue()->resetState();
getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4));
ENTITY_PARAM(0, 2) = 0;
@@ -997,7 +1000,7 @@ label_callback_8:
}
if (ENTITY_PARAM(0, 3)) {
- getSound()->resetState();
+ getSoundQueue()->resetState();
ENTITY_PARAM(0, 3) = 0;
}
break;
@@ -1149,8 +1152,8 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init)
if (savepoint.action != kActionDefault)
return;
- getSound()->processEntries();
- getSound()->resetState();
+ getSoundQueue()->processEntries();
+ getSoundQueue()->resetState();
getProgress().isTrainRunning = true;
@@ -1176,7 +1179,7 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init)
getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 3) = 0;
}
@@ -1213,11 +1216,11 @@ IMPLEMENT_FUNCTION(19, Chapters, chapter4Handler)
break;
case 0:
- getSound()->playSound(kEntityPlayer, "ZFX1008", (SoundManager::FlagType)(rnd(15) + 2));
+ getSound()->playSound(kEntityPlayer, "ZFX1008", (SoundFlag)(rnd(15) + 2));
break;
case 1:
- getSound()->playSound(kEntityPlayer, "ZFX1009", (SoundManager::FlagType)(rnd(15) + 2));
+ getSound()->playSound(kEntityPlayer, "ZFX1009", (SoundFlag)(rnd(15) + 2));
break;
}
@@ -1318,7 +1321,7 @@ label_callback_4:
}
if (ENTITY_PARAM(0, 3)) {
- getSound()->resetState();
+ getSoundQueue()->resetState();
ENTITY_PARAM(0, 3) = 0;
} else if (!params->param2 && !params->param3) {
getSound()->playSound(kEntityChapters, "ZFX1001");
@@ -1355,17 +1358,17 @@ label_callback_4:
goto label_callback_4;
case 5:
- if (getSound()->isBuffered(kEntityChapters))
- getSound()->removeFromQueue(kEntityChapters);
+ if (getSoundQueue()->isBuffered(kEntityChapters))
+ getSoundQueue()->removeFromQueue(kEntityChapters);
getAction()->playAnimation(kEventTrainExplosionBridge);
getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
break;
case 6:
- getSound()->processEntries();
+ getSoundQueue()->processEntries();
getAction()->playAnimation(kEventTylerCastleDream);
- getSound()->resetState();
+ getSoundQueue()->resetState();
getProgress().field_18 = 1;
@@ -1417,7 +1420,7 @@ label_callback_4:
case 11:
getScenes()->loadSceneFromPosition(kCarRedSleeping, 74);
- getSound()->playSound(kEntityTrain, "ZFX4001", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityTrain, "ZFX4001", kFlagDefault);
getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
break;
}
@@ -1464,17 +1467,17 @@ label_callback_4:
params->param1 = 1;
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 3) = 0;
}
- getSound()->playSound(kEntityPlayer, "MUS008", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
getInventory()->unselectItem();
- while (getSound()->isBuffered("MUS008"))
- getSound()->updateQueue();
+ while (getSoundQueue()->isBuffered("MUS008"))
+ getSoundQueue()->updateQueue();
if (getInventory()->hasItem(kItemBomb)) {
RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function47);
@@ -1521,8 +1524,8 @@ label_callback_4:
case kAction191001984:
getState()->time = kTime2520000;
- if (getSound()->isBuffered(kEntityChapters))
- getSound()->removeFromQueue(kEntityChapters);
+ if (getSoundQueue()->isBuffered(kEntityChapters))
+ getSoundQueue()->removeFromQueue(kEntityChapters);
getEntities()->clearSequences(kEntityChapters);
getInventory()->removeItem(kItemTelegram);
@@ -1534,10 +1537,10 @@ label_callback_4:
break;
case kAction201959744:
- if (getSound()->isBuffered(kEntityChapters))
- getSound()->removeFromQueue(kEntityChapters);
+ if (getSoundQueue()->isBuffered(kEntityChapters))
+ getSoundQueue()->removeFromQueue(kEntityChapters);
- getSound()->playSound(kEntityTrain, "ZFX4001", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityTrain, "ZFX4001", kFlagDefault);
getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
break;
@@ -1643,7 +1646,7 @@ IMPLEMENT_FUNCTION(21, Chapters, chapter5Init)
getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation2);
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 3) = 0;
}
@@ -1673,8 +1676,8 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
params->param2 = 1;
if (!getProgress().isNightTime) {
- getSound()->playSound(kEntityChapters, "ARRIVE", SoundManager::kFlag8);
- getSound()->processEntries();
+ getSound()->playSound(kEntityChapters, "ARRIVE", kFlag8);
+ getSoundQueue()->processEntries();
}
}
@@ -1682,8 +1685,8 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
params->param3 = 1;
if (!getEvent(kEventLocomotiveMilosDay) && !getEvent(kEventLocomotiveMilosNight)) {
- getSound()->playSound(kEntityChapters, "ARRIVE", SoundManager::kFlag8);
- getSound()->processEntries();
+ getSound()->playSound(kEntityChapters, "ARRIVE", kFlag8);
+ getSoundQueue()->processEntries();
}
}
break;
@@ -1712,8 +1715,8 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
getProgress().isNightTime = true;
getState()->time = kTime2916000;
- if (getSound()->isBuffered(kEntityChapters))
- getSound()->removeFromQueue(kEntityChapters);
+ if (getSoundQueue()->isBuffered(kEntityChapters))
+ getSoundQueue()->removeFromQueue(kEntityChapters);
break;
}
IMPLEMENT_FUNCTION_END
@@ -1729,7 +1732,7 @@ void Chapters::enterExitStation(const SavePoint &savepoint, bool isEnteringStati
return;
}
- getSound()->removeFromQueue(kEntityChapters);
+ getSoundQueue()->removeFromQueue(kEntityChapters);
if (!ENTITY_PARAM(0, 2)) {
if (ENTITY_PARAM(0, 3))
@@ -1796,8 +1799,8 @@ void Chapters::enterExitStation(const SavePoint &savepoint, bool isEnteringStati
void Chapters::enterExitHelper(bool isEnteringStation) {
EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
- getSound()->playSound(kEntityChapters, isEnteringStation ? "ARRIVE" : "DEPART", SoundManager::kFlag8);
- getSound()->processEntries();
+ getSound()->playSound(kEntityChapters, isEnteringStation ? "ARRIVE" : "DEPART", kFlag8);
+ getSoundQueue()->processEntries();
getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand);
getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand);
diff --git a/engines/lastexpress/entities/cooks.cpp b/engines/lastexpress/entities/cooks.cpp
index 336f911800..42e888cc7c 100644
--- a/engines/lastexpress/entities/cooks.cpp
+++ b/engines/lastexpress/entities/cooks.cpp
@@ -26,9 +26,11 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -101,7 +103,7 @@ IMPLEMENT_FUNCTION(3, Cooks, function3)
if (getEntities()->isPlayerPosition(kCarRestaurant, 46)) {
getEntities()->drawSequenceLeft(kEntityCooks, "308D");
- if (!getSound()->isBuffered(kEntityCooks)) {
+ if (!getSoundQueue()->isBuffered(kEntityCooks)) {
if (params->param1) {
if (!getEntities()->hasValidFrame(kEntityCooks)) {
getSound()->playSound(kEntityCooks, "LIB015");
@@ -187,7 +189,7 @@ IMPLEMENT_FUNCTION(4, Cooks, function4)
if (getEntities()->isPlayerPosition(kCarRestaurant, 80)) {
getEntities()->drawSequenceLeft(kEntityCooks, "308D");
- if (!getSound()->isBuffered(kEntityCooks)) {
+ if (!getSoundQueue()->isBuffered(kEntityCooks)) {
if (params->param1) {
if (!getEntities()->hasValidFrame(kEntityCooks)) {
getSound()->playSound(kEntityCooks, "LIB015");
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
index e74471ebca..c3e7e37b88 100644
--- a/engines/lastexpress/entities/coudert.cpp
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -29,9 +29,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -258,7 +260,7 @@ IMPLEMENT_FUNCTION_NOSETUP(7, Coudert, playSound16)
break;
case kActionDefault:
- getSound()->playSound(kEntityCoudert, (char *)&params->seq1, SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityCoudert, (char *)&params->seq1, kFlagDefault);
break;
case kActionCallback:
@@ -314,7 +316,7 @@ IMPLEMENT_FUNCTION_II(9, Coudert, updateEntity, CarIndex, EntityPosition)
case kActionExcuseMeCath:
if (getData()->clothes == kClothes1)
getSound()->playSound(kEntityPlayer, "ZFX1003", getSound()->getSoundFlag(kEntityCoudert));
- else if (!getSound()->isBuffered(kEntityCoudert))
+ else if (!getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playSound(kEntityPlayer, "JAC1112", getSound()->getSoundFlag(kEntityCoudert));
break;
@@ -409,7 +411,7 @@ IMPLEMENT_FUNCTION_I(12, Coudert, excuseMe, EntityIndex)
if (savepoint.action != kActionDefault)
return;
- if (getSound()->isBuffered(kEntityCoudert)) {
+ if (getSoundQueue()->isBuffered(kEntityCoudert)) {
CALLBACK_ACTION();
return;
}
@@ -823,7 +825,7 @@ IMPLEMENT_FUNCTION(18, Coudert, function18)
getScenes()->loadSceneFromItemPosition(kItem5);
if (getEntities()->isPlayerPosition(kCarRedSleeping, 68)) {
- if (!getSound()->isBuffered(kEntityCoudert))
+ if (!getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playSound(kEntityCoudert, "JAC1111");
getScenes()->loadSceneFromPosition(kCarRedSleeping, 25);
@@ -1642,7 +1644,7 @@ IMPLEMENT_FUNCTION_I(31, Coudert, function31, uint32)
break;
case 1:
- if (getSound()->isBuffered(kEntityCoudert)) {
+ if (getSoundQueue()->isBuffered(kEntityCoudert)) {
getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
} else {
setCallback(2);
@@ -1929,7 +1931,7 @@ IMPLEMENT_FUNCTION_I(35, Coudert, function35, bool)
break;
case 1:
- if (!getSound()->isBuffered(kEntityCoudert))
+ if (!getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playSound(kEntityCoudert, "Ann3124");
if (params->param1)
@@ -2008,8 +2010,8 @@ IMPLEMENT_FUNCTION(37, Coudert, function37)
break;
case kActionDefault:
- if (getSound()->isBuffered(kEntityCoudert))
- getSound()->processEntry(kEntityCoudert);
+ if (getSoundQueue()->isBuffered(kEntityCoudert))
+ getSoundQueue()->processEntry(kEntityCoudert);
if (ENTITY_PARAM(0, 7)) {
getData()->entityPosition = kPosition_8200;
@@ -2268,7 +2270,7 @@ label_callback_8:
}
label_callback_9:
- if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityCoudert))
+ if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playSound(kEntityCoudert, rnd(2) ? "JAC1065" : "JAC1065A");
if (getState()->time > kTime1107000 && !ENTITY_PARAM(0, 1) && !getEvent(kEventVassiliSeizure)) {
@@ -3019,7 +3021,7 @@ IMPLEMENT_FUNCTION(46, Coudert, function46)
// Fallback to next case
case 7:
- if (getSound()->isBuffered(kEntityCoudert)) {
+ if (getSoundQueue()->isBuffered(kEntityCoudert)) {
setCallback(7);
setup_updateFromTime(75);
} else {
@@ -3088,7 +3090,7 @@ IMPLEMENT_FUNCTION_I(47, Coudert, function47, bool)
// Fallback to next case
case 4:
- if (getSound()->isBuffered(kEntityCoudert)) {
+ if (getSoundQueue()->isBuffered(kEntityCoudert)) {
setCallback(4);
setup_updateFromTime(225);
} else {
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index 22750989fb..e136ca4776 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -33,9 +33,10 @@
#include "lastexpress/game/state.h"
#include "lastexpress/game/savegame.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -104,24 +105,24 @@ void EntityData::EntityCallData::saveLoadWithSerializer(Common::Serializer &s) {
//////////////////////////////////////////////////////////////////////////
EntityData::EntityParameters *EntityData::getParameters(uint callback, byte index) const {
if (callback >= 9)
- error("EntityData::getParameters: invalid callback value (was: %d, max: 9)", callback);
+ error("[EntityData::getParameters] Invalid callback value (was: %d, max: 9)", callback);
if (index >= 4)
- error("EntityData::getParameters: invalid index value (was: %d, max: 4)", index);
+ error("[EntityData::getParameters] Invalid index value (was: %d, max: 4)", index);
return _parameters[callback].parameters[index];
}
int EntityData::getCallback(uint callback) const {
if (callback >= 16)
- error("EntityData::getParameters: invalid callback value (was: %d, max: 16)", callback);
+ error("[EntityData::getCallback] Invalid callback value (was: %d, max: 16)", callback);
return _data.callbacks[callback];
}
void EntityData::setCallback(uint callback, byte index) {
if (callback >= 16)
- error("EntityData::getParameters: invalid callback value (was: %d, max: 16)", callback);
+ error("[EntityData::setCallback] Invalid callback value (was: %d, max: 16)", callback);
_data.callbacks[callback] = index;
}
@@ -136,7 +137,7 @@ void EntityData::updateParameters(uint32 index) const {
else if (index < 32)
getParameters(8, 3)->update(index - 24);
else
- error("EntityData::updateParameters: invalid param index to update (was:%d, max:32)!", index);
+ error("[EntityData::updateParameters] Invalid param index to update (was:%d, max:32)", index);
}
void EntityData::saveLoadWithSerializer(Common::Serializer &s) {
@@ -255,7 +256,7 @@ void Entity::savegame(const SavePoint &savepoint) {
}
}
-void Entity::playSound(const SavePoint &savepoint, bool resetItem, SoundManager::FlagType flag) {
+void Entity::playSound(const SavePoint &savepoint, bool resetItem, SoundFlag flag) {
EXPOSE_PARAMS(EntityData::EntityParametersSIIS)
switch (savepoint.action) {
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
index 01cf17f791..039f461c7b 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -25,7 +25,7 @@
#include "lastexpress/shared.h"
-#include "lastexpress/game/sound.h"
+#include "lastexpress/sound/sound.h"
#include "lastexpress/helpers.h"
@@ -85,7 +85,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersIIII::update: invalid index (was: %d)", index);
+ error("[EntityParametersIIII::update] Invalid index (was: %d)", index);
case 0: param1 = 1; break;
case 1: param2 = 1; break;
@@ -134,7 +134,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersSIII::update: invalid index (was: %d)", index);
+ error("[EntityParametersSIII::update] Invalid index (was: %d)", index);
case 3: param4 = 1; break;
case 4: param5 = 1; break;
@@ -174,7 +174,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersSIIS::update: invalid index (was: %d)", index);
+ error("[EntityParametersSIIS::update] Invalid index (was: %d)", index);
case 3: param4 = 1; break;
case 4: param5 = 1; break;
@@ -209,7 +209,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersISSI::update: invalid index (was: %d)", index);
+ error("[EntityParametersISSI::update] Invalid index (was: %d)", index);
case 0: param1 = 1; break;
case 7: param8 = 1; break;
@@ -248,7 +248,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersISII::update: invalid index (was: %d)", index);
+ error("[EntityParametersISII::update] Invalid index (was: %d)", index);
case 0: param1 = 1; break;
case 4: param5 = 1; break;
@@ -288,7 +288,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersSSII::update: invalid index (was: %d)", index);
+ error("[EntityParametersSSII::update] Invalid index (was: %d)", index);
case 6: param7 = 1; break;
case 7: param8 = 1; break;
@@ -319,7 +319,7 @@ public:
}
void update(uint32) {
- error("EntityParametersSSS::update: cannot update this type of parameters");
+ error("[EntityParametersSSS::update] Cannot update this type of parameters");
}
void saveLoadWithSerializer(Common::Serializer &s) {
@@ -349,7 +349,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersIISS::update: invalid index (was: %d)", index);
+ error("[EntityParametersIISS::update] Invalid index (was: %d)", index);
case 0: param1 = 1; break;
case 1: param2 = 1; break;
@@ -388,7 +388,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersIISI::update: invalid index (was: %d)", index);
+ error("[EntityParametersIISI::update] Invalid index (was: %d)", index);
case 0: param1 = 1; break;
case 1: param2 = 1; break;
@@ -432,7 +432,7 @@ public:
void update(uint32 index) {
switch (index) {
default:
- error("EntityParametersIIIS::update: invalid index (was: %d)", index);
+ error("[EntityParametersIIIS::update] Invalid index (was: %d)", index);
case 0: param1 = 1; break;
case 1: param2 = 1; break;
@@ -686,7 +686,7 @@ protected:
* @param resetItem true to reset item.
* @param flag sound flag
*/
- void playSound(const SavePoint &savepoint, bool resetItem = false, SoundManager::FlagType flag = SoundManager::kFlagInvalid);
+ void playSound(const SavePoint &savepoint, bool resetItem = false, SoundFlag flag = kFlagInvalid);
/**
* Draws the entity
diff --git a/engines/lastexpress/entities/entity_intern.h b/engines/lastexpress/entities/entity_intern.h
index 43d7f702c9..bf75e022de 100644
--- a/engines/lastexpress/entities/entity_intern.h
+++ b/engines/lastexpress/entities/entity_intern.h
@@ -96,7 +96,7 @@ void class::setup_##name() { \
#define EXPOSE_PARAMS(type) \
type *params = (type*)_data->getCurrentParameters(); \
if (!params) \
- error("Trying to call an entity function with invalid parameters!"); \
+ error("[EXPOSE_PARAMS] Trying to call an entity function with invalid parameters"); \
// function signature without setup (we keep the index for consistency but never use it)
@@ -413,7 +413,7 @@ void class::setup_##name() { \
//////////////////////////////////////////////////////////////////////////
#define CALLBACK_ACTION() { \
if (getData()->currentCall == 0) \
- error("CALLBACK_ACTION: currentCall is already 0, cannot proceed!"); \
+ error("[CALLBACK_ACTION] currentCall is already 0, cannot proceed"); \
getData()->currentCall--; \
getSavePoints()->setCallback(_entityIndex, _callbacks[_data->getCurrentCallback()]); \
getSavePoints()->call(_entityIndex, _entityIndex, kActionCallback); \
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
index 86b6820499..6bbe740730 100644
--- a/engines/lastexpress/entities/francois.cpp
+++ b/engines/lastexpress/entities/francois.cpp
@@ -30,6 +30,8 @@
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -275,7 +277,7 @@ IMPLEMENT_FUNCTION_I(11, Francois, function11, TimeValue)
break;
case kActionNone:
- if (!getSound()->isBuffered(kEntityFrancois)) {
+ if (!getSoundQueue()->isBuffered(kEntityFrancois)) {
UPDATE_PARAM_PROC(CURRENT_PARAM(1, 1), getState()->timeTicks, params->param6)
switch (rnd(7)) {
@@ -370,8 +372,8 @@ label_callback:
getData()->field_4A3 = 30;
getData()->inventoryItem = kItemNone;
- if (getSound()->isBuffered(kEntityFrancois))
- getSound()->processEntry(kEntityFrancois);
+ if (getSoundQueue()->isBuffered(kEntityFrancois))
+ getSoundQueue()->processEntry(kEntityFrancois);
setCallback(4);
setup_updateEntity(kCarRedSleeping, kPosition_5790);
@@ -381,8 +383,8 @@ label_callback:
case kAction1:
getData()->inventoryItem = kItemNone;
- if (getSound()->isBuffered(kEntityFrancois))
- getSound()->processEntry(kEntityFrancois);
+ if (getSoundQueue()->isBuffered(kEntityFrancois))
+ getSoundQueue()->processEntry(kEntityFrancois);
setCallback(6);
setup_savegame(kSavegameTypeEvent, kEventFrancoisWhistle);
diff --git a/engines/lastexpress/entities/gendarmes.cpp b/engines/lastexpress/entities/gendarmes.cpp
index f5ae191f9d..daa50956d3 100644
--- a/engines/lastexpress/entities/gendarmes.cpp
+++ b/engines/lastexpress/entities/gendarmes.cpp
@@ -88,12 +88,12 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_S(5, Gendarmes, arrestPlaysound16)
- arrest(savepoint, true, SoundManager::kFlagDefault);
+ arrest(savepoint, true, kFlagDefault);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_I(6, Gendarmes, arrestCallback, uint32)
- arrest(savepoint, true, SoundManager::kFlagInvalid, true);
+ arrest(savepoint, true, kFlagInvalid, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -103,7 +103,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_II(8, Gendarmes, arrestUpdateEntity, CarIndex, EntityPosition)
- arrest(savepoint, true, SoundManager::kFlagInvalid, false, true);
+ arrest(savepoint, true, kFlagInvalid, false, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -221,7 +221,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, function9, CarIndex, EntityPosition)
strcpy(arrestSound, "POL1043");
strcat(arrestSound, (char *)&params->seq2);
- getSound()->playSound(kEntityGendarmes, arrestSound, SoundManager::kFlagInvalid, 30);
+ getSound()->playSound(kEntityGendarmes, arrestSound, kFlagInvalid, 30);
}
getData()->location = kLocationInsideCompartment;
@@ -264,7 +264,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
if (params->param6 == 0 || getState()->timeTicks > (uint32)params->param6) {
params->param6 = kTimeInvalid;
- getSound()->playSound(kEntityGendarmes, "POL1046A", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityGendarmes, "POL1046A", kFlagDefault);
}
UPDATE_PARAM(params->param7, getState()->timeTicks, 300);
@@ -276,7 +276,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
if (getEntities()->isOutsideAlexeiWindow())
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
- getSound()->playSound(kEntityGendarmes, "LIB017", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityGendarmes, "LIB017", kFlagDefault);
setCallback(getProgress().jacket == kJacketBlood ? 3 : 4);
setup_savegame(kSavegameTypeEvent, getProgress().jacket == kJacketBlood ? kEventMertensBloodJacket : kEventGendarmesArrestation);
@@ -312,7 +312,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
break;
case 2:
- getSound()->playSound(kEntityGendarmes, "LIB014", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityGendarmes, "LIB014", kFlagDefault);
getAction()->playAnimation(kEventGendarmesArrestation);
getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
break;
@@ -338,7 +338,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
break;
case 6:
- getSound()->playSound(kEntityGendarmes, "LIB014", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityGendarmes, "LIB014", kFlagDefault);
getAction()->playAnimation(kEventGendarmesArrestation);
getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
break;
@@ -544,7 +544,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
// Private functions
//////////////////////////////////////////////////////////////////////////
-void Gendarmes::arrest(const SavePoint &savepoint, bool shouldPlaySound, SoundManager::FlagType flag, bool checkCallback, bool shouldUpdateEntity) {
+void Gendarmes::arrest(const SavePoint &savepoint, bool shouldPlaySound, SoundFlag flag, bool checkCallback, bool shouldUpdateEntity) {
switch (savepoint.action) {
default:
break;
diff --git a/engines/lastexpress/entities/gendarmes.h b/engines/lastexpress/entities/gendarmes.h
index e8f9cb2c38..d999cfc1fd 100644
--- a/engines/lastexpress/entities/gendarmes.h
+++ b/engines/lastexpress/entities/gendarmes.h
@@ -26,7 +26,7 @@
#include "lastexpress/entities/entity.h"
#include "lastexpress/entities/entity_intern.h"
-#include "lastexpress/game/sound.h"
+#include "lastexpress/sound/sound.h"
namespace LastExpress {
@@ -88,7 +88,7 @@ public:
DECLARE_FUNCTION(chapter5)
private:
- void arrest(const SavePoint &savepoint, bool playSound = false, SoundManager::FlagType flag = SoundManager::kFlagInvalid, bool checkCallback = false, bool shouldUpdateEntity = false);
+ void arrest(const SavePoint &savepoint, bool playSound = false, SoundFlag flag = kFlagInvalid, bool checkCallback = false, bool shouldUpdateEntity = false);
};
} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/hadija.cpp b/engines/lastexpress/entities/hadija.cpp
index ce2c9718db..8ec972b939 100644
--- a/engines/lastexpress/entities/hadija.cpp
+++ b/engines/lastexpress/entities/hadija.cpp
@@ -26,9 +26,10 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/ivo.cpp b/engines/lastexpress/entities/ivo.cpp
index 35f4ccfb8c..f2261b438c 100644
--- a/engines/lastexpress/entities/ivo.cpp
+++ b/engines/lastexpress/entities/ivo.cpp
@@ -22,16 +22,18 @@
#include "lastexpress/entities/ivo.h"
+#include "lastexpress/fight/fight.h"
+
#include "lastexpress/game/action.h"
#include "lastexpress/game/entities.h"
-#include "lastexpress/game/fight.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp
index 6472ce0533..2918b1e8bd 100644
--- a/engines/lastexpress/entities/kahina.cpp
+++ b/engines/lastexpress/entities/kahina.cpp
@@ -29,9 +29,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -607,8 +609,8 @@ label_callback_3:
break;
if (getEvent(kEventKahinaAskSpeakFirebird)) {
- if (getSound()->isBuffered(kEntityKahina))
- getSound()->processEntry(kEntityKahina);
+ if (getSoundQueue()->isBuffered(kEntityKahina))
+ getSoundQueue()->processEntry(kEntityKahina);
if (savepoint.action == kActionKnock)
getSound()->playSound(kEntityPlayer, "LIB012");
@@ -1163,8 +1165,8 @@ IMPLEMENT_FUNCTION(24, Kahina, function24)
case 1:
if (ENTITY_PARAM(0, 2)) {
getEntities()->clearSequences(kEntityKahina);
- if (getSound()->isBuffered(kEntityKahina))
- getSound()->processEntry(kEntityKahina);
+ if (getSoundQueue()->isBuffered(kEntityKahina))
+ getSoundQueue()->processEntry(kEntityKahina);
getProgress().field_44 = 0;
@@ -1186,7 +1188,7 @@ IMPLEMENT_FUNCTION(24, Kahina, function24)
getEntities()->updateEntity(kEntityKahina, kCarKronos, kPosition_9270);
getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750));
getSavePoints()->push(kEntityKahina, kEntityKronos, kAction235599361);
- getSound()->playSound(kEntityKahina, "MUS016", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityKahina, "MUS016", kFlagDefault);
getProgress().field_44 = 1;
params->param1 = true;
@@ -1198,8 +1200,8 @@ IMPLEMENT_FUNCTION(24, Kahina, function24)
case kAction137503360:
getEntities()->clearSequences(kEntityKahina);
- if (getSound()->isBuffered(kEntityKahina))
- getSound()->processEntry(kEntityKahina);
+ if (getSoundQueue()->isBuffered(kEntityKahina))
+ getSoundQueue()->processEntry(kEntityKahina);
getProgress().field_44 = 0;
diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp
index 925b0967b7..134dce9c81 100644
--- a/engines/lastexpress/entities/kronos.cpp
+++ b/engines/lastexpress/entities/kronos.cpp
@@ -36,9 +36,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -216,7 +218,7 @@ IMPLEMENT_FUNCTION(11, Kronos, function11)
case kActionDefault:
getData()->entityPosition = kPosition_7000;
- if (!getSound()->isBuffered(kEntityKronos))
+ if (!getSoundQueue()->isBuffered(kEntityKronos))
getSound()->playSound(kEntityKronos, "KRO1001");
break;
}
@@ -457,7 +459,7 @@ IMPLEMENT_FUNCTION(19, Kronos, function19)
case 2:
getAction()->playAnimation(kEventConcertStart);
- getSound()->setupEntry(SoundManager::kSoundType7, kEntityKronos);
+ getSoundQueue()->setupEntry(kSoundType7, kEntityKronos);
getScenes()->loadSceneFromPosition(kCarKronos, 83);
RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_function39);
@@ -480,7 +482,7 @@ IMPLEMENT_FUNCTION(20, Kronos, function20)
break;
case kActionNone:
- params->param5 = getSound()->getEntryTime(kEntityKronos)* 2;
+ params->param5 = getSoundQueue()->getEntryTime(kEntityKronos)* 2;
if (params->param6 < ARRAYSIZE(concertData) && params->param5 > concertData[params->param6].time) {
@@ -560,8 +562,8 @@ IMPLEMENT_FUNCTION(20, Kronos, function20)
case 3:
getAction()->playAnimation(kEventCathFallingAsleep);
- while (getSound()->isBuffered("1919.LNK"))
- getSound()->updateQueue();
+ while (getSoundQueue()->isBuffered("1919.LNK"))
+ getSoundQueue()->updateQueue();
getAction()->playAnimation(kEventCathWakingUp);
getScenes()->processScene();
@@ -746,7 +748,7 @@ IMPLEMENT_FUNCTION(22, Kronos, function22)
case kActionKnock:
case kActionOpenDoor:
- if (!getSound()->isBuffered(savepoint.action == kActionKnock ? "LIB012" : "LIB013", true))
+ if (!getSoundQueue()->isBuffered(savepoint.action == kActionKnock ? "LIB012" : "LIB013", true))
getSound()->playSound(kEntityPlayer, savepoint.action == kActionKnock ? "LIB012" : "LIB013");
if (getEvent(kEventConcertLeaveWithBriefcase))
diff --git a/engines/lastexpress/entities/mahmud.cpp b/engines/lastexpress/entities/mahmud.cpp
index 7d30d31a84..0e67b45cd2 100644
--- a/engines/lastexpress/entities/mahmud.cpp
+++ b/engines/lastexpress/entities/mahmud.cpp
@@ -31,9 +31,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -157,7 +159,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
case kActionEndSound:
case kActionDrawScene:
- if (!getSound()->isBuffered(kEntityMahmud)) {
+ if (!getSoundQueue()->isBuffered(kEntityMahmud)) {
EntityPosition position = getEntityData(kEntityPlayer)->entityPosition;
if (position < kPosition_1500 || position >= kPosition_5790 || (position > kPosition_4455 && params->param5 != 5)) {
getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
@@ -173,12 +175,12 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
case kActionKnock:
case kActionOpenDoor:
- if (!getSound()->isBuffered((savepoint.action == kActionKnock) ? "LIB012" : "LIB013", true))
+ if (!getSoundQueue()->isBuffered((savepoint.action == kActionKnock) ? "LIB012" : "LIB013", true))
getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock) ? "LIB012" : "LIB013");
params->param5 = savepoint.param.intValue;
- if (!getSound()->isBuffered(kEntityMahmud)) {
+ if (!getSoundQueue()->isBuffered(kEntityMahmud)) {
params->param3++;
switch(params->param3) {
@@ -204,7 +206,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
if (getState()->time >= kTimeCityGalanta) {
params->param3 = 0;
} else {
- getSound()->playSound(kEntityTrain, "LIB050", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityTrain, "LIB050", kFlagDefault);
getLogic()->gameOver(kSavegameTypeIndex, 0, (getProgress().chapter == kChapter1) ? kSceneGameOverPolice1 : kSceneGameOverPolice2, true);
}
break;
@@ -235,7 +237,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
break;
case kActionDefault:
- getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170A" : "MAH1173", SoundManager::kFlagInvalid, 45);
+ getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170A" : "MAH1173", kFlagInvalid, 45);
getProgress().field_C4 = 1;
setCallback(1);
@@ -282,7 +284,7 @@ IMPLEMENT_FUNCTION(11, Mahmud, function11)
case kActionOpenDoor: {
getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock ? "LIB012" : "LIB013"));
- if (!getSound()->isBuffered(kEntityMahmud)) {
+ if (!getSoundQueue()->isBuffered(kEntityMahmud)) {
params->param1++;
getSound()->playSound(kEntityMahmud, (params->param1 == 1 ? "MAH1170E" : (params->param1 == 2 ? "MAH1173B" : "MAH1174")));
@@ -396,8 +398,8 @@ IMPLEMENT_FUNCTION(11, Mahmud, function11)
break;
case kAction123852928:
- if (getSound()->isBuffered(kEntityMahmud))
- getSound()->processEntry(kEntityMahmud);
+ if (getSoundQueue()->isBuffered(kEntityMahmud))
+ getSoundQueue()->processEntry(kEntityMahmud);
getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectCompartment6, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
@@ -560,7 +562,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler)
TIME_CHECK_CALLBACK(kTime1098000, params->param6, 1, setup_function13);
- if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
+ if (!getSoundQueue()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
params->param7 = 1;
setCallback(2);
@@ -636,7 +638,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler)
params->param4 = 0;
params->param5 = 0;
- if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
+ if (!getSoundQueue()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
params->param7 = 1;
setCallback(2);
setup_function12();
diff --git a/engines/lastexpress/entities/max.cpp b/engines/lastexpress/entities/max.cpp
index 7e5931322d..eacc38bf60 100644
--- a/engines/lastexpress/entities/max.cpp
+++ b/engines/lastexpress/entities/max.cpp
@@ -28,9 +28,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -91,7 +93,7 @@ IMPLEMENT_FUNCTION(6, Max, chapter12_handler)
case kActionNone:
UPDATE_PARAM(params->param2, getState()->time, params->param1);
- if (!getSound()->isBuffered(kEntityMax))
+ if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max1122");
params->param1 = 255 * (4 * rnd(20) + 40);
@@ -108,7 +110,7 @@ IMPLEMENT_FUNCTION(6, Max, chapter12_handler)
break;
case kAction158007856:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
getSound()->playSound(kEntityMax, "Max1122");
params->param1 = 255 * (4 * rnd(20) + 40);
}
@@ -125,7 +127,7 @@ IMPLEMENT_FUNCTION(7, Max, function7)
case kActionNone:
UPDATE_PARAM(params->param2, getState()->time, params->param1)
- if (!getSound()->isBuffered(kEntityMax))
+ if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max1122");
params->param1 = 255 * (4 * rnd(20) + 40);
@@ -137,8 +139,8 @@ IMPLEMENT_FUNCTION(7, Max, function7)
getObjects()->update(kObjectCompartmentF, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal);
getObjects()->update(kObject53, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal);
- if (getSound()->isBuffered(kEntityMax))
- getSound()->processEntry(kEntityMax);
+ if (getSoundQueue()->isBuffered(kEntityMax))
+ getSoundQueue()->processEntry(kEntityMax);
setCallback((savepoint.action == kActionKnock) ? 1 : 2);
setup_playSound((savepoint.action == kActionKnock) ? "LIB012" : "LIB013");
@@ -156,7 +158,7 @@ IMPLEMENT_FUNCTION(7, Max, function7)
break;
case kActionDrawScene:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
if (getEntities()->isPlayerPosition(kCarRedSleeping, 56) || getEntities()->isPlayerPosition(kCarRedSleeping, 78))
getSound()->playSound(kEntityMax, "Max1120");
}
@@ -197,7 +199,7 @@ IMPLEMENT_FUNCTION(7, Max, function7)
break;
case kAction158007856:
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
getSound()->playSound(kEntityMax, "Max1122");
params->param1 = 255 * (4 * rnd(20) + 40);
}
@@ -214,7 +216,7 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
case kActionNone:
UPDATE_PARAM(params->param3, getState()->time, params->param2);
- if (!getSound()->isBuffered(kEntityMax))
+ if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max3101");
params->param2 = 255 * (4 * rnd(20) + 40);
@@ -228,8 +230,8 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
break;
}
- if (getSound()->isBuffered(kEntityMax))
- getSound()->processEntry(kEntityMax);
+ if (getSoundQueue()->isBuffered(kEntityMax))
+ getSoundQueue()->processEntry(kEntityMax);
getAction()->playAnimation(kEventCathMaxLickHand);
getScenes()->processScene();
@@ -247,7 +249,7 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
getData()->location = kLocationInsideCompartment;
getData()->car = kCarBaggage;
- if (!getSound()->isBuffered(kEntityMax))
+ if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max3101");
break;
@@ -255,8 +257,8 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
if (getCallback() != 1)
break;
- if (getSound()->isBuffered(kEntityMax))
- getSound()->processEntry(kEntityMax);
+ if (getSoundQueue()->isBuffered(kEntityMax))
+ getSoundQueue()->processEntry(kEntityMax);
getSound()->playSound(kEntityPlayer, "LIB026");
getAction()->playAnimation(kEventCathMaxFree);
@@ -392,7 +394,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
UPDATE_PARAM(params->param3, getState()->time, params->param1);
- if (!getSound()->isBuffered(kEntityMax))
+ if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max1122");
params->param1 = 255 * (4 * rnd(20) + 40);
@@ -424,7 +426,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
if (params->param2)
break;
- if (!getSound()->isBuffered(kEntityMax)) {
+ if (!getSoundQueue()->isBuffered(kEntityMax)) {
getSound()->playSound(kEntityMax, "Max1122");
params->param1 = 255 * (4 * rnd(20) + 40);
}
@@ -464,7 +466,7 @@ IMPLEMENT_FUNCTION(14, Max, freeFromCage)
getData()->location = kLocationInsideCompartment;
getData()->car = kCarBaggage;
- if (!getSound()->isBuffered(kEntityMax))
+ if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max1122");
break;
@@ -476,17 +478,17 @@ IMPLEMENT_FUNCTION(14, Max, freeFromCage)
break;
case 1:
- if (getSound()->isBuffered(kEntityMax))
- getSound()->removeFromQueue(kEntityMax);
+ if (getSoundQueue()->isBuffered(kEntityMax))
+ getSoundQueue()->removeFromQueue(kEntityMax);
getAction()->playAnimation(kEventCathMaxCage);
- getSound()->setupEntry(SoundManager::kSoundType7, kEntityMax);
+ getSoundQueue()->setupEntry(kSoundType7, kEntityMax);
getScenes()->processScene();
break;
case 2:
- if (getSound()->isBuffered(kEntityMax))
- getSound()->processEntry(kEntityMax);
+ if (getSoundQueue()->isBuffered(kEntityMax))
+ getSoundQueue()->processEntry(kEntityMax);
getSound()->playSound(kEntityPlayer, "LIB026");
getAction()->playAnimation(kEventCathMaxFree);
@@ -523,7 +525,7 @@ IMPLEMENT_FUNCTION(15, Max, function15)
getData()->location = kLocationOutsideCompartment;
getData()->car = kCarRedSleeping;
- if (!getSound()->isBuffered(kEntityMax))
+ if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max3010");
setCallback(1);
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
index 91082f487e..e222af4805 100644
--- a/engines/lastexpress/entities/mertens.cpp
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -30,7 +30,9 @@
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
#include "lastexpress/game/state.h"
-#include "lastexpress/game/sound.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -289,7 +291,7 @@ IMPLEMENT_FUNCTION_S(8, Mertens, playSound16)
break;
case kActionDefault:
- getSound()->playSound(kEntityMertens, (char *)&params->seq1, SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityMertens, (char *)&params->seq1, kFlagDefault);
break;
case kActionCallback:
@@ -503,7 +505,7 @@ IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
if (savepoint.action == kActionDefault)
return;
- if (getSound()->isBuffered(kEntityMertens)) {
+ if (getSoundQueue()->isBuffered(kEntityMertens)) {
CALLBACK_ACTION();
return;
}
@@ -589,7 +591,7 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
if (params->param2)
params->param3 = 1;
- if (!getSound()->isBuffered(kEntityMertens)) {
+ if (!getSoundQueue()->isBuffered(kEntityMertens)) {
}
@@ -896,7 +898,7 @@ IMPLEMENT_FUNCTION(17, Mertens, function17)
} else {
// Got the passenger list, Mertens is looking for it before sitting
ENTITY_PARAM(0, 2) = 1;
- getSound()->playSound(kEntityMertens, "CON1058", SoundManager::kFlagInvalid, 75);
+ getSound()->playSound(kEntityMertens, "CON1058", kFlagInvalid, 75);
getEntities()->drawSequenceRight(kEntityMertens, "601D");
}
@@ -984,7 +986,7 @@ IMPLEMENT_FUNCTION(18, Mertens, function18)
getEntities()->drawSequenceRight(kEntityMertens, "601A");
} else {
ENTITY_PARAM(0, 2) = 1;
- getSound()->playSound(kEntityMertens, "CON1058", SoundManager::kFlagInvalid, 75);
+ getSound()->playSound(kEntityMertens, "CON1058", kFlagInvalid, 75);
getEntities()->drawSequenceRight(kEntityMertens, "601D");
}
@@ -1188,7 +1190,7 @@ IMPLEMENT_FUNCTION(22, Mertens, function22)
break;
case 5:
- if (!getSound()->isBuffered(kEntityMertens))
+ if (!getSoundQueue()->isBuffered(kEntityMertens))
getSound()->playSound(kEntityMertens, "MAH1170I");
setCallback(6);
@@ -1198,8 +1200,8 @@ IMPLEMENT_FUNCTION(22, Mertens, function22)
case 6:
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityMertens);
- if (!getSound()->isBuffered(kEntityMertens))
- getSound()->playSound(kEntityMertens, "MAH1172", SoundManager::kFlagInvalid, 225);
+ if (!getSoundQueue()->isBuffered(kEntityMertens))
+ getSound()->playSound(kEntityMertens, "MAH1172", kFlagInvalid, 225);
setCallback(7);
setup_function21(kObjectCompartment4, kObject20);
@@ -2300,7 +2302,7 @@ IMPLEMENT_FUNCTION_I(31, Mertens, function31, MertensActionType)
break;
case 1:
- if (getSound()->isBuffered(kEntityMertens)) {
+ if (getSoundQueue()->isBuffered(kEntityMertens)) {
getEntities()->drawSequenceLeft(kEntityMertens, "601J");
} else {
setCallback(2);
@@ -3017,7 +3019,7 @@ IMPLEMENT_FUNCTION(42, Mertens, function42)
if (getState()->time <= kTime1188000) {
if ((!getEntities()->isPlayerInCar(kCarGreenSleeping) && !getEntities()->isPlayerInCar(kCarRedSleeping))
- || getSound()->isBuffered("REB1205")
+ || getSoundQueue()->isBuffered("REB1205")
|| !getEntities()->isInsideCompartment(kEntityMmeBoutarel, kCarRedSleeping, kPosition_5790)
|| !params->param4) {
params->param4 = (uint)getState()->time;
@@ -3138,7 +3140,7 @@ label_callback_18:
}
label_callback_19:
- if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityMertens)) {
+ if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityMertens)) {
if (getProgress().field_18 != 4)
getSound()->playSound(kEntityMertens, "CON1505");
}
diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp
index 587c43cade..ff3d2b6744 100644
--- a/engines/lastexpress/entities/milos.cpp
+++ b/engines/lastexpress/entities/milos.cpp
@@ -24,17 +24,20 @@
#include "lastexpress/entities/vesna.h"
+#include "lastexpress/fight/fight.h"
+
#include "lastexpress/game/action.h"
#include "lastexpress/game/entities.h"
-#include "lastexpress/game/fight.h"
#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -110,7 +113,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_S(7, Milos, playSound16)
- Entity::playSound(savepoint, false, SoundManager::kFlagDefault);
+ Entity::playSound(savepoint, false, kFlagDefault);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -1576,8 +1579,8 @@ IMPLEMENT_FUNCTION(29, Milos, chapter4Handler)
break;
case kAction221683008:
- if (getSound()->isBuffered(kEntityMilos))
- getSound()->processEntry(kEntityMilos);
+ if (getSoundQueue()->isBuffered(kEntityMilos))
+ getSoundQueue()->processEntry(kEntityMilos);
params->param1 = 1;
getSavePoints()->push(kEntityMilos, kEntityCoudert, kAction123199584);
@@ -1719,15 +1722,15 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
break;
case 2:
- if (getSound()->isBuffered("MUS050"))
- getSound()->processEntry("MUS050");
+ if (getSoundQueue()->isBuffered("MUS050"))
+ getSoundQueue()->processEntry("MUS050");
- if (getSound()->isBuffered("ARRIVE"))
- getSound()->removeFromQueue("ARRIVE");
+ if (getSoundQueue()->isBuffered("ARRIVE"))
+ getSoundQueue()->removeFromQueue("ARRIVE");
- getSound()->processEntries();
+ getSoundQueue()->processEntries();
getAction()->playAnimation(isNight() ? kEventLocomotiveMilosNight : kEventLocomotiveMilosDay);
- getSound()->setupEntry(SoundManager::kSoundType7, kEntityMilos);
+ getSoundQueue()->setupEntry(kSoundType7, kEntityMilos);
getScenes()->loadSceneFromPosition(kCarCoalTender, 1);
break;
@@ -1739,7 +1742,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
case 4:
getAction()->playAnimation(kEventLocomotiveRestartTrain);
getAction()->playAnimation(kEventLocomotiveOldBridge);
- getSound()->resetState();
+ getSoundQueue()->resetState();
getState()->time = kTime2983500;
setCallback(5);
@@ -1782,7 +1785,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
setup_savegame(kSavegameTypeEvent, kEventLocomotiveAnnaStopsTrain);
}
- getSound()->processEntry(kEntityMilos);
+ getSoundQueue()->processEntry(kEntityMilos);
if (getState()->time < kTimeTrainStopped2)
getState()->time = kTimeTrainStopped2;
diff --git a/engines/lastexpress/entities/mmeboutarel.cpp b/engines/lastexpress/entities/mmeboutarel.cpp
index 78f2d2fb4b..9ca10ca374 100644
--- a/engines/lastexpress/entities/mmeboutarel.cpp
+++ b/engines/lastexpress/entities/mmeboutarel.cpp
@@ -28,9 +28,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -399,7 +401,7 @@ IMPLEMENT_FUNCTION(13, MmeBoutarel, function13)
break;
case kActionNone:
- if (!getSound()->isBuffered(kEntityMmeBoutarel) && params->param6 != kTimeInvalid) {
+ if (!getSoundQueue()->isBuffered(kEntityMmeBoutarel) && params->param6 != kTimeInvalid) {
UPDATE_PARAM_PROC_TIME(params->param1, !getEntities()->isDistanceBetweenEntities(kEntityMmeBoutarel, kEntityPlayer, 2000), params->param6, 0)
getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
@@ -883,8 +885,8 @@ IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler)
if (getState()->time <= kTime2038500) {
if (!getEntities()->isPlayerInCar(kCarRedSleeping)
|| !params->param1
- || getSound()->isBuffered("FRA2012")
- || getSound()->isBuffered("FRA2010")
+ || getSoundQueue()->isBuffered("FRA2012")
+ || getSoundQueue()->isBuffered("FRA2010")
||!params->param2)
params->param2 = (uint)getState()->time;
diff --git a/engines/lastexpress/entities/pascale.cpp b/engines/lastexpress/entities/pascale.cpp
index 7cf7f7766e..a191273702 100644
--- a/engines/lastexpress/entities/pascale.cpp
+++ b/engines/lastexpress/entities/pascale.cpp
@@ -27,9 +27,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -141,15 +143,15 @@ IMPLEMENT_FUNCTION(8, Pascale, welcomeSophieAndRebecca)
break;
case kChapter1:
- getSound()->playSound(kEntityPascale, "REB1198", SoundManager::kFlagInvalid, 30);
+ getSound()->playSound(kEntityPascale, "REB1198", kFlagInvalid, 30);
break;
case kChapter3:
- getSound()->playSound(kEntityPascale, "REB3001", SoundManager::kFlagInvalid, 30);
+ getSound()->playSound(kEntityPascale, "REB3001", kFlagInvalid, 30);
break;
case kChapter4:
- getSound()->playSound(kEntityPascale, "REB4001", SoundManager::kFlagInvalid, 30);
+ getSound()->playSound(kEntityPascale, "REB4001", kFlagInvalid, 30);
break;
}
@@ -201,7 +203,7 @@ IMPLEMENT_FUNCTION(10, Pascale, welcomeCath)
break;
case kActionNone:
- if (params->param1 && !getSound()->isBuffered(kEntityPascale))
+ if (params->param1 && !getSoundQueue()->isBuffered(kEntityPascale))
getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 64);
break;
@@ -462,10 +464,10 @@ IMPLEMENT_FUNCTION(16, Pascale, serveTatianaVassili)
getEntities()->drawSequenceLeft(kEntityPascale, "014B");
getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 67);
- if (getSound()->isBuffered("TAT1069A"))
- getSound()->processEntry("TAT1069A");
- else if (getSound()->isBuffered("TAT1069B"))
- getSound()->processEntry("TAT1069B");
+ if (getSoundQueue()->isBuffered("TAT1069A"))
+ getSoundQueue()->processEntry("TAT1069A");
+ else if (getSoundQueue()->isBuffered("TAT1069B"))
+ getSoundQueue()->processEntry("TAT1069B");
setCallback(2);
setup_playSound("TAT1066");
@@ -754,7 +756,7 @@ IMPLEMENT_FUNCTION(24, Pascale, welcomeAbbot)
break;
case kActionDefault:
- getSound()->playSound(kEntityPascale, "ABB3015", SoundManager::kFlagInvalid, 105);
+ getSound()->playSound(kEntityPascale, "ABB3015", kFlagInvalid, 105);
getEntities()->drawSequenceRight(kEntityPascale, "029A1");
getEntities()->drawSequenceRight(kEntityAbbot, "029A2");
break;
@@ -1213,7 +1215,7 @@ label_callback1:
break;
case kAction169750080:
- if (getSound()->isBuffered(kEntityPascale)) {
+ if (getSoundQueue()->isBuffered(kEntityPascale)) {
params->param4 = 1;
} else {
setCallback(7);
diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp
index 1cb895d8d6..b1a176b47e 100644
--- a/engines/lastexpress/entities/rebecca.cpp
+++ b/engines/lastexpress/entities/rebecca.cpp
@@ -27,9 +27,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -316,7 +318,7 @@ IMPLEMENT_FUNCTION_I(17, Rebecca, function17, bool)
getData()->location = kLocationOutsideCompartment;
if (getProgress().chapter == kChapter3)
- getSound()->playSound(kEntityRebecca, "Reb3005", SoundManager::kFlagInvalid, 75);
+ getSound()->playSound(kEntityRebecca, "Reb3005", kFlagInvalid, 75);
if (params->param1) {
setCallback(5);
@@ -511,7 +513,7 @@ IMPLEMENT_FUNCTION_I(20, Rebecca, function20, TimeValue)
if (getProgress().chapter == kChapter1 && !ENTITY_PARAM(0, 3)) {
if (params->param7 != kTimeInvalid && getState()->time > kTime1174500) {
if (getState()->time <= kTime1183500) {
- if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 2000) || getSound()->isBuffered("CON1210") || !params->param7)
+ if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 2000) || getSoundQueue()->isBuffered("CON1210") || !params->param7)
params->param7 = (uint)(getState()->time);
if (params->param7 >= getState()->time)
@@ -1357,7 +1359,7 @@ label_callback_3:
params->param5 = kTimeInvalid;
getData()->inventoryItem = kItemNone;
- getSound()->playSound(kEntityRebecca, "Reb3008", SoundManager::kFlagInvalid, 60);
+ getSound()->playSound(kEntityRebecca, "Reb3008", kFlagInvalid, 60);
getEntities()->updatePositionEnter(kEntityRebecca, kCarRestaurant, 52);
setCallback(3);
diff --git a/engines/lastexpress/entities/salko.cpp b/engines/lastexpress/entities/salko.cpp
index 4d510bb9bf..63d995dc42 100644
--- a/engines/lastexpress/entities/salko.cpp
+++ b/engines/lastexpress/entities/salko.cpp
@@ -22,16 +22,19 @@
#include "lastexpress/entities/salko.h"
+#include "lastexpress/fight/fight.h"
+
#include "lastexpress/game/action.h"
#include "lastexpress/game/entities.h"
-#include "lastexpress/game/fight.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -595,8 +598,8 @@ IMPLEMENT_FUNCTION(24, Salko, chapter5Handler)
break;
case 1:
- if (getSound()->isBuffered("MUS050"))
- getSound()->processEntry("MUS050");
+ if (getSoundQueue()->isBuffered("MUS050"))
+ getSoundQueue()->processEntry("MUS050");
getAction()->playAnimation(kEventCathSalkoTrainTopFight);
diff --git a/engines/lastexpress/entities/servers0.cpp b/engines/lastexpress/entities/servers0.cpp
index 1fec775659..989bddd662 100644
--- a/engines/lastexpress/entities/servers0.cpp
+++ b/engines/lastexpress/entities/servers0.cpp
@@ -26,9 +26,10 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/servers1.cpp b/engines/lastexpress/entities/servers1.cpp
index cd0a162755..995fbbc01b 100644
--- a/engines/lastexpress/entities/servers1.cpp
+++ b/engines/lastexpress/entities/servers1.cpp
@@ -26,9 +26,10 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/sophie.cpp b/engines/lastexpress/entities/sophie.cpp
index e0c63f7297..57bd491949 100644
--- a/engines/lastexpress/entities/sophie.cpp
+++ b/engines/lastexpress/entities/sophie.cpp
@@ -25,9 +25,10 @@
#include "lastexpress/game/entities.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/tables.cpp b/engines/lastexpress/entities/tables.cpp
index c372663c40..06ea4c597c 100644
--- a/engines/lastexpress/entities/tables.cpp
+++ b/engines/lastexpress/entities/tables.cpp
@@ -26,9 +26,11 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -49,7 +51,7 @@ Tables::Tables(LastExpressEngine *engine, EntityIndex id) : Entity(engine, id) {
IMPLEMENT_FUNCTION(1, Tables, chapter1)
if (savepoint.action == kActionDefault) {
if (_id == kEntityTables2)
- getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", kFlagLoop, kEntityTables2);
setup_draw();
}
@@ -59,7 +61,7 @@ IMPLEMENT_FUNCTION_END
IMPLEMENT_FUNCTION(2, Tables, chapter2)
if (savepoint.action == kActionDefault) {
if (_id == kEntityTables2)
- getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", kFlagLoop, kEntityTables2);
setup_draw();
}
@@ -69,7 +71,7 @@ IMPLEMENT_FUNCTION_END
IMPLEMENT_FUNCTION(3, Tables, chapter3)
if (savepoint.action == kActionDefault) {
if (_id == kEntityTables2)
- getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", kFlagLoop, kEntityTables2);
setup_draw();
}
@@ -79,7 +81,7 @@ IMPLEMENT_FUNCTION_END
IMPLEMENT_FUNCTION(4, Tables, chapter4)
if (savepoint.action == kActionDefault) {
if (_id == kEntityTables2)
- getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", kFlagLoop, kEntityTables2);
setup_draw();
}
@@ -88,8 +90,8 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(5, Tables, chapter5)
if (savepoint.action == kActionDefault) {
- if (_id == kEntityTables2 && getSound()->isBuffered(kEntityTables2))
- getSound()->processEntry(kEntityTables2);
+ if (_id == kEntityTables2 && getSoundQueue()->isBuffered(kEntityTables2))
+ getSoundQueue()->processEntry(kEntityTables2);
setup_draw();
}
@@ -113,21 +115,21 @@ IMPLEMENT_FUNCTION(6, Tables, draw)
case kChapter1:
if (getState()->time > kTime1165500 && !params->param1) {
params->param1 = 1;
- getSound()->processEntry(kEntityTables2);
+ getSoundQueue()->processEntry(kEntityTables2);
}
break;
case kChapter3:
if (getState()->time > kTime2052000 && !params->param2) {
params->param2 = 1;
- getSound()->processEntry(kEntityTables2);
+ getSoundQueue()->processEntry(kEntityTables2);
}
break;
case kChapter4:
if (getState()->time > kTime2488500 && !params->param3) {
params->param3 = 1;
- getSound()->processEntry(kEntityTables2);
+ getSoundQueue()->processEntry(kEntityTables2);
}
break;
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
index 6e25d8c5c7..c8901b3e30 100644
--- a/engines/lastexpress/entities/tatiana.cpp
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -32,9 +32,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -420,7 +422,7 @@ IMPLEMENT_FUNCTION(19, Tatiana, chapter1Handler)
break;
case kActionNone:
- if (getSound()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSound()->isBuffered("TAT1066"))
+ if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSoundQueue()->isBuffered("TAT1066"))
goto label_tatiana_chapter1_2;
UPDATE_PARAM_PROC(params->param5, getState()->timeTicks, 450)
@@ -568,7 +570,7 @@ IMPLEMENT_FUNCTION(21, Tatiana, function21)
// Fallback to next case
case 3:
- if (getSound()->isBuffered(kEntityTatiana)) {
+ if (getSoundQueue()->isBuffered(kEntityTatiana)) {
setCallback(3);
setup_updateFromTime(75);
} else {
@@ -1858,7 +1860,7 @@ IMPLEMENT_FUNCTION(46, Tatiana, function46)
parameters->param3 = 1;
if (parameters->param2) {
- getSound()->removeFromQueue(kEntityTatiana);
+ getSoundQueue()->removeFromQueue(kEntityTatiana);
getSavePoints()->call(kEntityTatiana, kEntityTatiana, kActionEndSound);
}
} else {
@@ -1947,12 +1949,12 @@ IMPLEMENT_FUNCTION(48, Tatiana, function48)
params->param1 = 0;
}
- if (!params->param1 || getSound()->isBuffered(kEntityTatiana))
+ if (!params->param1 || getSoundQueue()->isBuffered(kEntityTatiana))
goto label_end;
UPDATE_PARAM_GOTO(params->param2, getState()->timeTicks, 5 * (3 * rnd(5) + 30), label_end);
- getSound()->playSound(kEntityTatiana, "LIB012", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityTatiana, "LIB012", kFlagDefault);
params->param2 = 0;
label_end:
@@ -2086,7 +2088,7 @@ IMPLEMENT_FUNCTION(50, Tatiana, function50)
break;
case kActionKnock:
- if (!getSound()->isBuffered("LIB012", true))
+ if (!getSoundQueue()->isBuffered("LIB012", true))
getSound()->playSound(kEntityPlayer, "LIB012");
break;
@@ -2107,14 +2109,14 @@ IMPLEMENT_FUNCTION(50, Tatiana, function50)
getObjects()->update(kObject48, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectCompartmentA, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
- if (!getSound()->isBuffered(kEntityTatiana))
+ if (!getSoundQueue()->isBuffered(kEntityTatiana))
getSound()->playSound(kEntityTatiana, "Tat4166");
break;
case kActionCallback:
if (getCallback() == 1) {
- if (getSound()->isBuffered("MUS013"))
- getSound()->processEntry("MUS013");
+ if (getSoundQueue()->isBuffered("MUS013"))
+ getSoundQueue()->processEntry("MUS013");
getAction()->playAnimation(kEventVassiliDeadAlexei);
getSavePoints()->push(kEntityTatiana, kEntityAbbot, kAction104060776);
@@ -2223,11 +2225,11 @@ IMPLEMENT_FUNCTION(54, Tatiana, function54)
case kActionCallback:
if (getCallback() == 1) {
- if (getSound()->isBuffered("MUS050"))
- getSound()->processEntry("MUS050");
+ if (getSoundQueue()->isBuffered("MUS050"))
+ getSoundQueue()->processEntry("MUS050");
- if (getSound()->isBuffered(kEntityTatiana))
- getSound()->processEntry(kEntityTatiana);
+ if (getSoundQueue()->isBuffered(kEntityTatiana))
+ getSoundQueue()->processEntry(kEntityTatiana);
getAction()->playAnimation(isNight() ? kEventTatianaVassiliTalkNight : kEventTatianaVassiliTalk);
getScenes()->processScene();
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
index 19c6fe279c..bced1da62b 100644
--- a/engines/lastexpress/entities/train.cpp
+++ b/engines/lastexpress/entities/train.cpp
@@ -30,7 +30,9 @@
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
#include "lastexpress/game/state.h"
-#include "lastexpress/game/sound.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -90,7 +92,7 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
switch (params->param1) {
default:
- error("Train::harem: Invalid value for parameter 1: %d", params->param1);
+ error("[Train::harem] Invalid value for parameter 1: %d", params->param1);
break;
case kObjectCompartment5:
@@ -118,7 +120,7 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
getObjects()->update((ObjectIndex)params->param1, kEntityTrain, kObjectLocation3, kCursorNormal, kCursorNormal);
// Knock / closed door sound
- getSound()->playSound(kEntityTables5, (params->param2 == 8) ? "LIB012" : "LIB013", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityTables5, (params->param2 == 8) ? "LIB012" : "LIB013", kFlagDefault);
if (params->param4 && params->param5) {
@@ -130,17 +132,17 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
break;
case 1:
- getSound()->playSound(kEntityTables5, "Har1014", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1014", kFlagDefault, 15);
break;
case 2:
- getSound()->playSound(kEntityTables5, "Har1013", SoundManager::kFlagDefault, 15);
- getSound()->playSound(kEntityTables5, "Har1016", SoundManager::kFlagDefault, 150);
+ getSound()->playSound(kEntityTables5, "Har1013", kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1016", kFlagDefault, 150);
break;
case 3:
- getSound()->playSound(kEntityTables5, "Har1015A", SoundManager::kFlagDefault, 15);
- getSound()->playSound(kEntityTables5, "Har1015", SoundManager::kFlagDefault, 150);
+ getSound()->playSound(kEntityTables5, "Har1015A", kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1015", kFlagDefault, 150);
break;
}
@@ -164,15 +166,15 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
break;
case 1:
- getSound()->playSound(kEntityTables5, "Har1014", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1014", kFlagDefault, 15);
break;
case 2:
- getSound()->playSound(kEntityTables5, "Har1013", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1013", kFlagDefault, 15);
break;
case 3:
- getSound()->playSound(kEntityTables5, "Har1013A", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1013A", kFlagDefault, 15);
break;
}
@@ -191,11 +193,11 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
break;
case 1:
- getSound()->playSound(kEntityTables5, "Har1012", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1012", kFlagDefault, 15);
break;
case 2:
- getSound()->playSound(kEntityTables5, "Har1012A", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1012A", kFlagDefault, 15);
break;
}
@@ -207,7 +209,7 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
ENTITY_PARAM(0, 1)++;
if (ENTITY_PARAM(0, 1) <= 1)
- getSound()->playSound(kEntityTables5, "Har1014", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1014", kFlagDefault, 15);
else
params->param8 = 1;
@@ -221,7 +223,7 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
ENTITY_PARAM(0, 4)++;
if (ENTITY_PARAM(0, 4) <= 1) {
- getSound()->playSound(kEntityTables5, "Har1011", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1011", kFlagDefault, 15);
handleCompartmentAction();
return;
}
@@ -241,11 +243,11 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
break;
case 1:
- getSound()->playSound(kEntityTables5, "Har1013", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1013", kFlagDefault, 15);
break;
case 2:
- getSound()->playSound(kEntityTables5, "Har1013A", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1013A", kFlagDefault, 15);
break;
}
@@ -300,13 +302,13 @@ label_process:
}
// Update object
- if (ENTITY_PARAM(0, 8) && !getSound()->isBuffered(kEntityTables5)) {
+ if (ENTITY_PARAM(0, 8) && !getSoundQueue()->isBuffered(kEntityTables5)) {
getObjects()->update((ObjectIndex)ENTITY_PARAM(0, 8), getObjects()->get((ObjectIndex)ENTITY_PARAM(0, 8)).entity, kObjectLocation3, kCursorHandKnock, kCursorHand);
ENTITY_PARAM(0, 8) = 0;
}
// Play clock sound
- if (params->param6 && !getSound()->isBuffered("ZFX1001", true))
+ if (params->param6 && !getSoundQueue()->isBuffered("ZFX1001", true))
getSound()->playSound(kEntityPlayer, "ZFX1001");
break;
@@ -339,12 +341,12 @@ label_process:
// Play clock sound
if (getEntities()->isPlayerPosition(kCarRestaurant, 81)) {
params->param6 = 1;
- if (!getSound()->isBuffered("ZFX1001"))
+ if (!getSoundQueue()->isBuffered("ZFX1001"))
getSound()->playSound(kEntityPlayer, "ZFX1001");
} else {
params->param6 = 0;
- if (getSound()->isBuffered("ZFX1001", true))
- getSound()->removeFromQueue("ZFX1001");
+ if (getSoundQueue()->isBuffered("ZFX1001", true))
+ getSoundQueue()->removeFromQueue("ZFX1001");
}
// Draw moving background behind windows
@@ -562,8 +564,8 @@ void Train::resetParam8() {
&& !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param2)
&& !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param3)) {
- if (getSound()->isBuffered((const char *)&params1->seq))
- getSound()->processEntry((const char *)&params1->seq);
+ if (getSoundQueue()->isBuffered((const char *)&params1->seq))
+ getSoundQueue()->processEntry((const char *)&params1->seq);
params->param8 = 0;
}
diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp
index 09fb5b1223..22f41afa92 100644
--- a/engines/lastexpress/entities/vassili.cpp
+++ b/engines/lastexpress/entities/vassili.cpp
@@ -32,9 +32,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -268,7 +270,7 @@ IMPLEMENT_FUNCTION(8, Vassili, function8)
getSavePoints()->push(kEntityVassili, kEntityAnna, kAction226031488);
getSavePoints()->push(kEntityVassili, kEntityVerges, kAction226031488);
getSavePoints()->push(kEntityVassili, kEntityCoudert, kAction226031488);
- getSound()->playSound(kEntityVassili, "VAS1027", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityVassili, "VAS1027", kFlagDefault);
break;
}
IMPLEMENT_FUNCTION_END
@@ -295,12 +297,12 @@ IMPLEMENT_FUNCTION(9, Vassili, function9)
|| getEntities()->isPlayerPosition(kCarRedSleeping, 41)) {
if (savepoint.action == kActionDrawScene)
- getSound()->processEntry(kEntityVassili);
+ getSoundQueue()->processEntry(kEntityVassili);
setup_seizure();
} else {
if (savepoint.action == kActionDefault)
- getSound()->playSound(kEntityVassili, "VAS1028", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityVassili, "VAS1028", kFlagDefault);
}
break;
}
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
index bc35a105b1..8246f85145 100644
--- a/engines/lastexpress/entities/verges.cpp
+++ b/engines/lastexpress/entities/verges.cpp
@@ -29,9 +29,11 @@
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -123,7 +125,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_NOSETUP(5, Verges, playSound16)
- Entity::playSound(savepoint, false, SoundManager::kFlagDefault);
+ Entity::playSound(savepoint, false, kFlagDefault);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -139,7 +141,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_II(8, Verges, updateEntity, CarIndex, EntityPosition)
if (savepoint.action == kActionExcuseMeCath) {
- if (!getSound()->isBuffered(kEntityVerges))
+ if (!getSoundQueue()->isBuffered(kEntityVerges))
getSound()->playSound(kEntityPlayer, "TRA1113", getSound()->getSoundFlag(kEntityVerges));
return;
@@ -187,7 +189,7 @@ switch (savepoint.action) {
break;
case 2:
- if (!getSound()->isBuffered(kEntityVerges))
+ if (!getSoundQueue()->isBuffered(kEntityVerges))
getSound()->playSound(kEntityVerges, (char *)&params->seq1);
getEntities()->drawSequenceRight(kEntityVerges, "813DS");
@@ -232,7 +234,7 @@ IMPLEMENT_FUNCTION_IIS(10, Verges, function10, CarIndex, EntityPosition)
case kActionNone:
if (!params->param7) {
- if (!getSound()->isBuffered(kEntityVerges)) {
+ if (!getSoundQueue()->isBuffered(kEntityVerges)) {
getSound()->playSound(kEntityVerges, (char *)&params->seq);
params->param7 = 1;
}
@@ -258,7 +260,7 @@ IMPLEMENT_FUNCTION_IIS(10, Verges, function10, CarIndex, EntityPosition)
break;
case kActionDefault:
- if (!getSound()->isBuffered(kEntityVerges)) {
+ if (!getSoundQueue()->isBuffered(kEntityVerges)) {
getSound()->playSound(kEntityVerges, (char *)&params->seq);
params->param7 = 1;
}
@@ -699,12 +701,12 @@ IMPLEMENT_FUNCTION(24, Verges, policeGettingOffTrain)
break;
case kActionDefault:
- getSound()->playSound(kEntityVerges, "POL1101", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityVerges, "POL1101", kFlagDefault);
break;
case kActionCallback:
if (getCallback() == 1) {
- getSound()->processEntry(kEntityVerges);
+ getSoundQueue()->processEntry(kEntityVerges);
getAction()->playAnimation(kEventGendarmesArrestation);
getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
}
@@ -1314,7 +1316,7 @@ IMPLEMENT_FUNCTION(32, Verges, function32)
break;
case 2:
- if (!getSound()->isBuffered(kEntityVerges))
+ if (!getSoundQueue()->isBuffered(kEntityVerges))
getSound()->playSound(kEntityVerges, "TRA3004");
getEntities()->drawSequenceRight(kEntityVerges, "813DS");
@@ -1752,16 +1754,16 @@ IMPLEMENT_FUNCTION(40, Verges, chapter5Handler)
break;
case kActionNone:
- if (getEntities()->isInSalon(kEntityPlayer) && !getSound()->isBuffered(kEntityVerges))
+ if (getEntities()->isInSalon(kEntityPlayer) && !getSoundQueue()->isBuffered(kEntityVerges))
getSound()->playSound(kEntityVerges, "WAT5000");
break;
case kActionOpenDoor:
- if (getSound()->isBuffered(kEntityVerges))
- getSound()->processEntry(kEntityVerges);
+ if (getSoundQueue()->isBuffered(kEntityVerges))
+ getSoundQueue()->processEntry(kEntityVerges);
- if (getSound()->isBuffered("MUS050"))
- getSound()->processEntry("MUS050");
+ if (getSoundQueue()->isBuffered("MUS050"))
+ getSoundQueue()->processEntry("MUS050");
getObjects()->update(kObject65, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
@@ -1811,7 +1813,7 @@ IMPLEMENT_FUNCTION(41, Verges, function41)
// Fallback to next case
case 2:
- if (getSound()->isBuffered(kEntityVerges)) {
+ if (getSoundQueue()->isBuffered(kEntityVerges)) {
setCallback(2);
setup_updateFromTime(225);
} else {
diff --git a/engines/lastexpress/entities/vesna.cpp b/engines/lastexpress/entities/vesna.cpp
index 8e09dbf7b0..7a1f1d3195 100644
--- a/engines/lastexpress/entities/vesna.cpp
+++ b/engines/lastexpress/entities/vesna.cpp
@@ -22,16 +22,18 @@
#include "lastexpress/entities/vesna.h"
+#include "lastexpress/fight/fight.h"
+
#include "lastexpress/game/action.h"
#include "lastexpress/game/entities.h"
-#include "lastexpress/game/fight.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -1082,7 +1084,7 @@ IMPLEMENT_FUNCTION(30, Vesna, function30)
case kActionNone:
if (!params->param1) {
UPDATE_PARAM_PROC(params->param3, getState()->timeTicks, 120)
- getSound()->playSound(kEntityVesna, "Ves50001", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityVesna, "Ves50001", kFlagDefault);
params->param1 = 1;
UPDATE_PARAM_PROC_END
}
@@ -1145,7 +1147,7 @@ IMPLEMENT_FUNCTION(30, Vesna, function30)
setCallback(2);
setup_savegame(kSavegameTypeEvent, kEventCathVesnaTrainTopKilled);
} else {
- getSound()->playSound(kEntityVesna, "Ves5001", SoundManager::kFlagDefault);
+ getSound()->playSound(kEntityVesna, "Ves5001", kFlagDefault);
params->param1 = 1;
}
break;
diff --git a/engines/lastexpress/entities/yasmin.cpp b/engines/lastexpress/entities/yasmin.cpp
index 7e8b2f7348..45e5e11568 100644
--- a/engines/lastexpress/entities/yasmin.cpp
+++ b/engines/lastexpress/entities/yasmin.cpp
@@ -26,9 +26,10 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/fight/fight.cpp b/engines/lastexpress/fight/fight.cpp
new file mode 100644
index 0000000000..b832d46a60
--- /dev/null
+++ b/engines/lastexpress/fight/fight.cpp
@@ -0,0 +1,409 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/fight/fight.h"
+
+#include "lastexpress/fight/fighter_anna.h"
+#include "lastexpress/fight/fighter_ivo.h"
+#include "lastexpress/fight/fighter_milos.h"
+#include "lastexpress/fight/fighter_salko.h"
+#include "lastexpress/fight/fighter_vesna.h"
+
+#include "lastexpress/data/cursor.h"
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/game/inventory.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/sound/queue.h"
+
+#include "lastexpress/graphics.h"
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+Fight::FightData::FightData() {
+ player = NULL;
+ opponent = NULL;
+
+ index = 0;
+
+ isFightRunning = false;
+}
+
+Fight::FightData::~FightData() {
+ SAFE_DELETE(player);
+ SAFE_DELETE(opponent);
+}
+
+Fight::Fight(LastExpressEngine *engine) : _engine(engine), _data(NULL), _endType(kFightEndLost), _state(0), _handleTimer(false) {
+}
+
+Fight::~Fight() {
+ clearData();
+ _data = NULL;
+
+ // Zero passed pointers
+ _engine = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Events
+//////////////////////////////////////////////////////////////////////////
+void Fight::eventMouse(const Common::Event &ev) {
+ if (!_data || _data->index)
+ return;
+
+ // TODO move all the egg handling to inventory functions
+
+ getFlags()->mouseLeftClick = false;
+ getFlags()->shouldRedraw = false;
+ getFlags()->mouseRightClick = false;
+
+ if (ev.mouse.x < 608 || ev.mouse.y < 448 || ev.mouse.x >= 640 || ev.mouse.x >= 480) {
+
+ // Handle right button click
+ if (ev.type == Common::EVENT_RBUTTONUP) {
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ setStopped();
+
+ getGlobalTimer() ? _state = 0 : ++_state;
+
+ getFlags()->mouseRightClick = true;
+ }
+
+ if (_handleTimer) {
+ // Timer expired => show with full brightness
+ if (!getGlobalTimer())
+ getInventory()->drawBlinkingEgg();
+
+ _handleTimer = false;
+ }
+
+ // Check hotspots
+ Scene *scene = getScenes()->get(getState()->scene);
+ SceneHotspot *hotspot = NULL;
+
+ if (!scene->checkHotSpot(ev.mouse, &hotspot)) {
+ _engine->getCursor()->setStyle(kCursorNormal);
+ } else {
+ _engine->getCursor()->setStyle((CursorStyle)hotspot->cursor);
+
+ // Call player function
+ if (_data->player->canInteract((Fighter::FightAction)hotspot->action)) {
+ if (ev.type == Common::EVENT_LBUTTONUP)
+ _data->player->handleAction((Fighter::FightAction)hotspot->action);
+ } else {
+ _engine->getCursor()->setStyle(kCursorNormal);
+ }
+ }
+ } else {
+ // Handle clicks on menu icon
+
+ if (!_handleTimer) {
+ // Timer expired => show with full brightness
+ if (!getGlobalTimer())
+ getInventory()->drawBlinkingEgg();
+
+ _handleTimer = true;
+ }
+
+ // Stop fight if clicked
+ if (ev.type == Common::EVENT_LBUTTONUP) {
+ _handleTimer = false;
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ bailout(kFightEndExit);
+ }
+
+ // Reset timer on right click
+ if (ev.type == Common::EVENT_RBUTTONUP) {
+ if (getGlobalTimer()) {
+ if (getSoundQueue()->isBuffered("TIMER"))
+ getSoundQueue()->removeFromQueue("TIMER");
+
+ setGlobalTimer(900);
+ }
+ }
+ }
+
+ getFlags()->shouldRedraw = true;
+}
+
+void Fight::eventTick(const Common::Event &ev) {
+ handleTick(ev, true);
+}
+
+void Fight::handleTick(const Common::Event &ev, bool isProcessing) {
+ // TODO move all the egg handling to inventory functions
+
+ // Blink egg
+ if (getGlobalTimer()) {
+ warning("[Fight::handleTick] Egg blinking not implemented");
+ }
+
+ if (!_data || _data->index)
+ return;
+
+ SceneHotspot *hotspot = NULL;
+ if (!getScenes()->get(getState()->scene)->checkHotSpot(ev.mouse, &hotspot) || !_data->player->canInteract((Fighter::FightAction)hotspot->action)) {
+ _engine->getCursor()->setStyle(kCursorNormal);
+ } else {
+ _engine->getCursor()->setStyle((CursorStyle)hotspot->cursor);
+ }
+
+ _data->player->update();
+ _data->opponent->update();
+
+ // Draw sequences
+ if (!_data->isFightRunning)
+ return;
+
+ if (isProcessing)
+ getScenes()->drawFrames(true);
+
+ if (_data->index) {
+ // Set next sequence name index
+ _data->index--;
+ _data->sequences[_data->index] = loadSequence(_data->names[_data->index]);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Setup
+//////////////////////////////////////////////////////////////////////////
+Fight::FightEndType Fight::setup(FightType type) {
+ if (_data)
+ error("[Fight::setup] Calling fight setup again while a fight is already in progress");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Prepare UI & state
+ if (_state >= 5 && (type == kFightSalko || type == kFightVesna)) {
+ _state = 0;
+ return kFightEndWin;
+ }
+
+ getInventory()->showHourGlass();
+ // TODO events function
+ getFlags()->flag_0 = false;
+ getFlags()->mouseRightClick = false;
+ getEntities()->reset();
+
+ // Compute scene to use
+ SceneIndex sceneIndex;
+ switch(type) {
+ default:
+ sceneIndex = kSceneFightDefault;
+ break;
+
+ case kFightMilos:
+ sceneIndex = (getObjects()->get(kObjectCompartment1).location2 < kObjectLocation3) ? kSceneFightMilos : kSceneFightMilosBedOpened;
+ break;
+
+ case kFightAnna:
+ sceneIndex = kSceneFightAnna;
+ break;
+
+ case kFightIvo:
+ sceneIndex = kSceneFightIvo;
+ break;
+
+ case kFightSalko:
+ sceneIndex = kSceneFightSalko;
+ break;
+
+ case kFightVesna:
+ sceneIndex = kSceneFightVesna;
+ break;
+ }
+
+ if (getFlags()->shouldRedraw) {
+ getFlags()->shouldRedraw = false;
+ askForRedraw();
+ //redrawScreen();
+ }
+
+ // Load the scene object
+ Scene *scene = getScenes()->get(sceneIndex);
+
+ // Update game entities and state
+ getEntityData(kEntityPlayer)->entityPosition = scene->entityPosition;
+ getEntityData(kEntityPlayer)->location = scene->location;
+
+ getState()->scene = sceneIndex;
+
+ getFlags()->flag_3 = true;
+
+ // Draw the scene
+ _engine->getGraphicsManager()->draw(scene, GraphicsManager::kBackgroundC);
+ // FIXME move to start of fight?
+ askForRedraw();
+ redrawScreen();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Setup the fight
+ _data = new FightData;
+ loadData(type);
+
+ // Show opponents & egg button
+ Common::Event emptyEvent;
+ handleTick(emptyEvent, false);
+ getInventory()->drawEgg();
+
+ // Start fight
+ _endType = kFightEndLost;
+ while (_data->isFightRunning) {
+ if (_engine->handleEvents())
+ continue;
+
+ getSoundQueue()->updateQueue();
+ }
+
+ // Cleanup after fight is over
+ clearData();
+
+ return _endType;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Status
+//////////////////////////////////////////////////////////////////////////
+void Fight::setStopped() {
+ if (_data)
+ _data->isFightRunning = false;
+}
+
+void Fight::bailout(FightEndType type) {
+ _state = 0;
+ _endType = type;
+ setStopped();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Cleanup
+//////////////////////////////////////////////////////////////////////////
+void Fight::clearData() {
+ if (!_data)
+ return;
+
+ // Clear data
+ SAFE_DELETE(_data);
+
+ _engine->restoreEventHandlers();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Loading
+//////////////////////////////////////////////////////////////////////////
+void Fight::loadData(FightType type) {
+ if (!_data)
+ error("[Fight::loadData] Data not initialized");
+
+ switch (type) {
+ default:
+ break;
+
+ case kFightMilos:
+ _data->player = new FighterPlayerMilos(_engine);
+ _data->opponent = new FighterOpponentMilos(_engine);
+ break;
+
+ case kFightAnna:
+ _data->player = new FighterPlayerAnna(_engine);
+ _data->opponent = new FighterOpponentAnna(_engine);
+ break;
+
+ case kFightIvo:
+ _data->player = new FighterPlayerIvo(_engine);
+ _data->opponent = new FighterOpponentIvo(_engine);
+ break;
+
+ case kFightSalko:
+ _data->player = new FighterPlayerSalko(_engine);
+ _data->opponent = new FighterOpponentSalko(_engine);
+ break;
+
+ case kFightVesna:
+ _data->player = new FighterPlayerVesna(_engine);
+ _data->opponent = new FighterOpponentVesna(_engine);
+ break;
+ }
+
+ if (!_data->player || !_data->opponent)
+ error("[Fight::loadData] Error loading fight data (type=%d)", type);
+
+ // Setup opponent pointers
+ setOpponents();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Start running the fight
+ _data->isFightRunning = true;
+
+ if (_state < 5) {
+ _data->player->setSequenceAndDraw(0, Fighter::kFightSequenceType0);
+ _data->opponent->setSequenceAndDraw(0, Fighter::kFightSequenceType0);
+ goto end_load;
+ }
+
+ switch(type) {
+ default:
+ break;
+
+ case kFightMilos:
+ _data->opponent->setCountdown(1);
+ _data->player->setSequenceAndDraw(4, Fighter::kFightSequenceType0);
+ _data->opponent->setSequenceAndDraw(0, Fighter::kFightSequenceType0);
+ break;
+
+ case kFightIvo:
+ _data->opponent->setCountdown(1);
+ _data->player->setSequenceAndDraw(3, Fighter::kFightSequenceType0);
+ _data->opponent->setSequenceAndDraw(6, Fighter::kFightSequenceType0);
+ break;
+
+ case kFightVesna:
+ _data->opponent->setCountdown(1);
+ _data->player->setSequenceAndDraw(0, Fighter::kFightSequenceType0);
+ _data->player->setSequenceAndDraw(3, Fighter::kFightSequenceType2);
+ _data->opponent->setSequenceAndDraw(5, Fighter::kFightSequenceType0);
+ break;
+ }
+
+end_load:
+ // Setup event handlers
+ _engine->backupEventHandlers();
+ SET_EVENT_HANDLERS(Fight, this);
+}
+
+void Fight::setOpponents() {
+ _data->player->setOpponent(_data->opponent);
+ _data->opponent->setOpponent(_data->player);
+
+ _data->player->setFight(this);
+ _data->opponent->setFight(this);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/fight/fight.h b/engines/lastexpress/fight/fight.h
new file mode 100644
index 0000000000..fffb520789
--- /dev/null
+++ b/engines/lastexpress/fight/fight.h
@@ -0,0 +1,125 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LASTEXPRESS_FIGHT_H
+#define LASTEXPRESS_FIGHT_H
+
+/*
+ Fight structure
+ ---------------
+ uint32 {4} - player struct
+ uint32 {4} - opponent struct
+ uint32 {4} - hasLost flag
+
+ byte {1} - isRunning
+
+ Fight participant structure
+ ---------------------------
+ uint32 {4} - function pointer
+ uint32 {4} - pointer to fight structure
+ uint32 {4} - pointer to opponent (fight participant structure)
+ uint32 {4} - array of sequences
+ uint32 {4} - number of sequences
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint16 {2} - ??
+ uint16 {2} - ?? - only for opponent structure
+ uint32 {4} - ?? - only for opponent structure
+
+*/
+
+#include "lastexpress/shared.h"
+
+#include "lastexpress/eventhandler.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class Sequence;
+
+class Fighter;
+class Opponent;
+
+class Fight : public EventHandler {
+public:
+ enum FightEndType {
+ kFightEndWin = 0,
+ kFightEndLost = 1,
+ kFightEndExit = 2
+ };
+
+ Fight(LastExpressEngine *engine);
+ ~Fight();
+
+ FightEndType setup(FightType type);
+
+ void eventMouse(const Common::Event &ev);
+ void eventTick(const Common::Event &ev);
+
+ // State
+ bool isRunning() { return _data->isFightRunning; }
+ void setRunningState(bool state) { _data->isFightRunning = state; }
+ void bailout(FightEndType type);
+ void setStopped();
+ void resetState() { _state = 0; }
+ void setEndType(FightEndType endType) { _endType = endType; }
+
+private:
+ struct FightData {
+ Fighter *player;
+ Opponent *opponent;
+ int32 index;
+
+ Sequence *sequences[20];
+ Common::String names[20];
+
+ bool isFightRunning;
+
+ FightData();
+ ~FightData();
+ };
+
+ LastExpressEngine *_engine;
+ FightData *_data;
+ FightEndType _endType;
+ int _state;
+
+ bool _handleTimer;
+
+ // Events
+ void handleTick(const Common::Event &ev, bool unknown);
+
+ // Data
+ void loadData(FightType type);
+ void clearData();
+ void setOpponents();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FIGHT_H
diff --git a/engines/lastexpress/fight/fighter.cpp b/engines/lastexpress/fight/fighter.cpp
new file mode 100644
index 0000000000..bae7728a2b
--- /dev/null
+++ b/engines/lastexpress/fight/fighter.cpp
@@ -0,0 +1,249 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/fight/fighter.h"
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/game/scenes.h"
+
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+namespace LastExpress {
+
+Fighter::Fighter(LastExpressEngine *engine) : _engine(engine) {
+ _opponent = NULL;
+ _fight = NULL;
+
+ _sequenceIndex = 0;
+ _sequence = NULL;
+ _frame = NULL;
+ _frameIndex = 0;
+
+ _field_24 = 0;
+
+ _action = kFightAction101;
+ _sequenceIndex2 = 0;
+
+ _countdown = 1;
+
+ _field_34 = 0;
+}
+
+Fighter::~Fighter() {
+ clearSequences();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Cleanup
+//////////////////////////////////////////////////////////////////////////
+void Fighter::clearSequences() {
+ // The original game resets the function pointers to default values, just before deleting the struct
+
+ getScenes()->removeAndRedraw(&_frame, false);
+
+ // Free sequences
+ for (int i = 0; i < (int)_sequences.size(); i++)
+ SAFE_DELETE(_sequences[i]);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Drawing
+//////////////////////////////////////////////////////////////////////////
+void Fighter::setSequenceAndDraw(uint32 sequenceIndex, FightSequenceType type) {
+ if (_sequences.size() < sequenceIndex)
+ return;
+
+ switch (type) {
+ default:
+ break;
+
+ case kFightSequenceType0:
+ if (_sequenceIndex)
+ return;
+
+ _sequence = _sequences[sequenceIndex];
+ _sequenceIndex = sequenceIndex;
+ draw();
+ break;
+
+ case kFightSequenceType1:
+ _sequence = _sequences[sequenceIndex];
+ _sequenceIndex = sequenceIndex;
+ _sequenceIndex2 = 0;
+ draw();
+ break;
+
+ case kFightSequenceType2:
+ _sequenceIndex2 = sequenceIndex;
+ break;
+ }
+}
+
+void Fighter::draw() {
+ getScenes()->removeAndRedraw(&_frame, false);
+
+ _frameIndex = 0;
+ _field_24 = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Processing
+//////////////////////////////////////////////////////////////////////////
+void Fighter::process() {
+ if (!_sequence) {
+ if (_frame) {
+ getScenes()->removeFromQueue(_frame);
+ getScenes()->setCoordinates(_frame);
+ }
+ SAFE_DELETE(_frame);
+ return;
+ }
+
+ if (_sequence->count() <= _frameIndex) {
+ switch(_action) {
+ default:
+ break;
+
+ case kFightAction101:
+ setSequenceAndDraw(_sequenceIndex2, kFightSequenceType1);
+ _sequenceIndex2 = 0;
+ break;
+
+ case kFightActionResetFrame:
+ _frameIndex = 0;
+ break;
+
+ case kFightAction103:
+ setSequenceAndDraw(0, kFightSequenceType1);
+ handleAction(kFightAction101);
+ _opponent->setSequenceAndDraw(0, kFightSequenceType1);
+ _opponent->handleAction(kFightAction101);
+ _opponent->update();
+ break;
+
+ case kFightActionWin:
+ _fight->bailout(Fight::kFightEndWin);
+ break;
+
+ case kFightActionLost:
+ _fight->bailout(Fight::kFightEndLost);
+ break;
+ }
+ }
+
+ if (_fight->isRunning()) {
+
+ // Get the current sequence frame
+ SequenceFrame *frame = new SequenceFrame(_sequence, (uint16)_frameIndex);
+ frame->getInfo()->location = 1;
+
+ if (_frame == frame) {
+ delete frame;
+ return;
+ }
+
+ getSound()->playFightSound(frame->getInfo()->soundAction, frame->getInfo()->field_31);
+
+ // Add current frame to queue and advance
+ getScenes()->addToQueue(frame);
+ _frameIndex++;
+
+ if (_frame) {
+ getScenes()->removeFromQueue(_frame);
+
+ if (!frame->getInfo()->field_2E)
+ getScenes()->setCoordinates(_frame);
+ }
+
+ // Replace by new frame
+ delete _frame;
+ _frame = frame;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Default actions
+//////////////////////////////////////////////////////////////////////////
+void Fighter::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ return;
+
+ case kFightAction101:
+ break;
+
+ case kFightActionResetFrame:
+ _countdown--;
+ break;
+
+ case kFightAction103:
+ _opponent->handleAction(kFightActionResetFrame);
+ break;
+
+ case kFightActionWin:
+ _fight->setEndType(Fight::kFightEndWin);
+ _opponent->handleAction(kFightActionResetFrame);
+ break;
+
+ case kFightActionLost:
+ _fight->setEndType(Fight::kFightEndLost);
+ _opponent->handleAction(kFightActionResetFrame);
+ break;
+ }
+
+ // Update action
+ _action = action;
+}
+
+bool Fighter::canInteract(FightAction /*action = kFightActionNone*/ ) {
+ return (_action == kFightAction101 && !_sequenceIndex);
+}
+
+void Fighter::update() {
+ process();
+
+ if (_frame)
+ _frame->getInfo()->location = (_action == kFightActionResetFrame ? 2 : 0);
+}
+
+void Opponent::update() {
+ process();
+
+ if (_field_38 && !_sequenceIndex)
+ _field_38--;
+
+ if (_frame)
+ _frame->getInfo()->location = 1;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Helpers
+//////////////////////////////////////////////////////////////////////////
+bool Fighter::checkFrame(uint32 val) {
+ return (_frame->getInfo()->field_33 & val);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/fight/fighter.h b/engines/lastexpress/fight/fighter.h
new file mode 100644
index 0000000000..e37fe49d86
--- /dev/null
+++ b/engines/lastexpress/fight/fighter.h
@@ -0,0 +1,123 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LASTEXPRESS_FIGHTER_H
+#define LASTEXPRESS_FIGHTER_H
+
+#include "lastexpress/fight/fight.h"
+
+#include "common/array.h"
+
+namespace LastExpress {
+
+class Fight;
+class Sequence;
+class SequenceFrame;
+
+class Fighter {
+public:
+ enum FightAction {
+ kFightActionNone = 0,
+ kFightAction1 = 1,
+ kFightAction2 = 2,
+ kFightAction3 = 3,
+ kFightAction4 = 4,
+ kFightAction5 = 5,
+ kFightAction101 = 101,
+ kFightActionResetFrame = 102,
+ kFightAction103 = 103,
+ kFightActionWin = 104,
+ kFightActionLost = 105,
+ kFightAction128 = 128,
+ kFightAction129 = 129,
+ kFightAction130 = 130,
+ kFightAction131 = 131,
+ kFightAction132 = 132
+ };
+
+ enum FightSequenceType {
+ kFightSequenceType0 = 0,
+ kFightSequenceType1 = 1,
+ kFightSequenceType2 = 2
+ };
+
+ Fighter(LastExpressEngine *engine);
+ virtual ~Fighter();
+
+ // Default functions
+ virtual void handleAction(FightAction action);
+ virtual void update();
+ virtual bool canInteract(FightAction action = kFightActionNone);
+
+ // Drawing
+ void setSequenceAndDraw(uint32 sequenceIndex, FightSequenceType type);
+
+ // Accessors
+ void setOpponent(Fighter *opponent) { _opponent = opponent; }
+ void setCountdown(int32 countdown) { _countdown = countdown; }
+ void setFight(Fight *fight) { _fight = fight; }
+
+ int getCountdown() { return _countdown; }
+ uint32 getSequenceIndex() { return _sequenceIndex; }
+ uint32 getField34() { return _field_34; }
+
+protected:
+ LastExpressEngine *_engine;
+ Fight *_fight;
+ Fighter *_opponent;
+ Sequence *_sequence;
+ SequenceFrame *_frame;
+ uint32 _sequenceIndex;
+ Common::Array<Sequence *> _sequences;
+ uint32 _frameIndex;
+ uint32 _field_24;
+ FightAction _action;
+ uint32 _sequenceIndex2;
+ int32 _countdown; // countdown before loosing ?
+ uint32 _field_34;
+
+ // Drawing and processing
+ void draw();
+ void process();
+
+ // Cleanup
+ void clearSequences();
+
+ // Helpers
+ bool checkFrame(uint32 val);
+};
+
+class Opponent : public Fighter {
+public:
+ Opponent(LastExpressEngine *engine) : Fighter(engine) {
+ _field_38 = 0;
+ }
+
+ virtual void update();
+
+protected:
+ int32 _field_38;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FIGHTER_H
diff --git a/engines/lastexpress/fight/fighter_anna.cpp b/engines/lastexpress/fight/fighter_anna.cpp
new file mode 100644
index 0000000000..c7660cab1a
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_anna.cpp
@@ -0,0 +1,187 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/fight/fighter_anna.h"
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// Player
+//////////////////////////////////////////////////////////////////////////
+FighterPlayerAnna::FighterPlayerAnna(LastExpressEngine *engine) : Fighter(engine) {
+ _sequences.push_back(loadSequence("2002cr.seq"));
+ _sequences.push_back(loadSequence("2002cdl.seq"));
+ _sequences.push_back(loadSequence("2002cdr.seq"));
+ _sequences.push_back(loadSequence("2002cdm.seq"));
+ _sequences.push_back(loadSequence("2002lbk.seq"));
+}
+
+void FighterPlayerAnna::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ Fighter::handleAction(action);
+ return;
+
+ case kFightAction1:
+ if ((_sequenceIndex != 1 && _sequenceIndex != 3) || checkFrame(4)) {
+ setSequenceAndDraw(4, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(4, kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction2:
+ if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) {
+ setSequenceAndDraw(4, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(5, kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction3:
+ if ((_sequenceIndex != 2 && _sequenceIndex != 1) || checkFrame(4)) {
+ setSequenceAndDraw(4, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(6, kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction128:
+ switch (_opponent->getSequenceIndex()) {
+ default:
+ setSequenceAndDraw(3, kFightSequenceType0);
+ break;
+
+ case 1:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 2:
+ setSequenceAndDraw(3, kFightSequenceType0);
+ break;
+
+ case 3:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+ }
+ break;
+ }
+
+ if (_field_34 > 4) {
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ _fight->bailout(Fight::kFightEndWin);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Opponent
+//////////////////////////////////////////////////////////////////////////
+FighterOpponentAnna::FighterOpponentAnna(LastExpressEngine *engine) : Opponent(engine) {
+ _sequences.push_back(loadSequence("2002or.seq"));
+ _sequences.push_back(loadSequence("2002oal.seq"));
+ _sequences.push_back(loadSequence("2002oam.seq"));
+ _sequences.push_back(loadSequence("2002oar.seq"));
+ _sequences.push_back(loadSequence("2002okr.seq"));
+ _sequences.push_back(loadSequence("2002okml.seq"));
+ _sequences.push_back(loadSequence("2002okm.seq"));
+
+ getSound()->playSound(kEntityTables0, "MUS030", kFlagDefault);
+
+ _field_38 = 30;
+}
+
+void FighterOpponentAnna::update() {
+ if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) {
+
+ if (_opponent->getField34() >= 2) {
+ switch (rnd(6)) {
+ default:
+ break;
+
+ case 0:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 1:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+
+ case 2:
+ setSequenceAndDraw(3, kFightSequenceType0);
+ break;
+
+ case 3:
+ setSequenceAndDraw(3, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+
+ case 4:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+
+ case 5:
+ setSequenceAndDraw(3, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+ }
+ }
+
+ // Update field_38
+ _field_38 = (int32)rnd(15);
+ }
+
+ if (_frame && checkFrame(2)) {
+ if (_sequenceIndex == 1 || _sequenceIndex == 2 || _sequenceIndex == 3)
+ _opponent->handleAction((FightAction)_sequenceIndex);
+
+ if (_opponent->getCountdown() <= 0) {
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ handleAction(kFightActionLost);
+ }
+ }
+
+ Fighter::update();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/fight/fighter_anna.h b/engines/lastexpress/fight/fighter_anna.h
new file mode 100644
index 0000000000..abb6f9dc64
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_anna.h
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LASTEXPRESS_FIGHTER_ANNA_H
+#define LASTEXPRESS_FIGHTER_ANNA_H
+
+#include "lastexpress/fight/fighter.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class FighterPlayerAnna : public Fighter {
+public:
+ FighterPlayerAnna(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+};
+
+class FighterOpponentAnna : public Opponent {
+public:
+ FighterOpponentAnna(LastExpressEngine *engine);
+
+ virtual void update();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FIGHTER_ANNA_H
diff --git a/engines/lastexpress/fight/fighter_ivo.cpp b/engines/lastexpress/fight/fighter_ivo.cpp
new file mode 100644
index 0000000000..87a52c6be4
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_ivo.cpp
@@ -0,0 +1,245 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/fight/fighter_ivo.h"
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// Player
+//////////////////////////////////////////////////////////////////////////
+FighterPlayerIvo::FighterPlayerIvo(LastExpressEngine *engine) : Fighter(engine) {
+ _sequences.push_back(loadSequence("2003cr.seq"));
+ _sequences.push_back(loadSequence("2003car.seq"));
+ _sequences.push_back(loadSequence("2003cal.seq"));
+ _sequences.push_back(loadSequence("2003cdr.seq"));
+ _sequences.push_back(loadSequence("2003cdm.seq"));
+ _sequences.push_back(loadSequence("2003chr.seq"));
+ _sequences.push_back(loadSequence("2003chl.seq"));
+ _sequences.push_back(loadSequence("2003ckr.seq"));
+ _sequences.push_back(loadSequence("2003lbk.seq"));
+ _sequences.push_back(loadSequence("2003fbk.seq"));
+
+ _countdown = 5;
+}
+
+void FighterPlayerIvo::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ Fighter::handleAction(action);
+ return;
+
+ case kFightAction1:
+ if (_sequenceIndex != 1 || checkFrame(4)) {
+ setSequenceAndDraw(7, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(4, kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+ update();
+ }
+ break;
+
+ case kFightAction2:
+ if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) {
+ setSequenceAndDraw(7, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(5, kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+ update();
+ }
+ break;
+
+ case kFightAction128:
+ switch (_opponent->getSequenceIndex()) {
+ default:
+ case 1:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 2:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+ }
+ break;
+
+ case kFightAction129:
+ setSequenceAndDraw((_opponent->getCountdown() > 1) ? 4 : 3, _sequenceIndex ? kFightSequenceType2 : kFightSequenceType0);
+ break;
+
+ case kFightAction130:
+ setSequenceAndDraw(3, _sequenceIndex ? kFightSequenceType2 : kFightSequenceType0);
+ break;
+ }
+}
+
+void FighterPlayerIvo::update() {
+
+ if ((_sequenceIndex == 3 || _sequenceIndex == 4) && !_frameIndex)
+ _opponent->handleAction(kFightAction131);
+
+ if (_frame && checkFrame(2)) {
+
+ // Draw sequences
+ if (_opponent->getCountdown() <= 0) {
+ setSequenceAndDraw(9, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(8, kFightSequenceType1);
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+
+ handleAction(kFightActionWin);
+ return;
+ }
+
+ if (_sequenceIndex == 3 || _sequenceIndex == 4)
+ _opponent->handleAction((FightAction)_sequenceIndex);
+ }
+
+ Fighter::update();
+}
+
+bool FighterPlayerIvo::canInteract(FightAction action) {
+ if (action == kFightAction129 || action == kFightAction130)
+ return (_sequenceIndex >= 8);
+
+ return Fighter::canInteract();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Opponent
+//////////////////////////////////////////////////////////////////////////
+FighterOpponentIvo::FighterOpponentIvo(LastExpressEngine *engine) : Opponent(engine) {
+ _sequences.push_back(loadSequence("2003or.seq"));
+ _sequences.push_back(loadSequence("2003oal.seq"));
+ _sequences.push_back(loadSequence("2003oar.seq"));
+ _sequences.push_back(loadSequence("2003odm.seq"));
+ _sequences.push_back(loadSequence("2003okl.seq"));
+ _sequences.push_back(loadSequence("2003okj.seq"));
+ _sequences.push_back(loadSequence("blank.seq"));
+ _sequences.push_back(loadSequence("csdr.seq"));
+ _sequences.push_back(loadSequence("2003l.seq"));
+
+ getSound()->playSound(kEntityTables0, "MUS032", kFlagDefault);
+
+ _countdown = 5;
+ _field_38 = 15;
+}
+
+void FighterOpponentIvo::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ Fighter::handleAction(action);
+ break;
+
+ case kFightAction3:
+ if ((_sequenceIndex != 1 && _sequenceIndex != 3) || checkFrame(4)) {
+ setSequenceAndDraw(6, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(6, kFightSequenceType1);
+ _opponent->handleAction(kFightAction103);
+ }
+ break;
+
+ case kFightAction4:
+ if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) {
+ setSequenceAndDraw(6, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(5, kFightSequenceType1);
+ _opponent->handleAction(kFightAction103);
+ }
+ break;
+
+ case kFightAction131:
+ if (_sequenceIndex)
+ break;
+
+ if (rnd(100) <= (unsigned int)(_countdown > 2 ? 60 : 75)) {
+ setSequenceAndDraw(3 , kFightSequenceType1);
+ if (_opponent->getSequenceIndex() == 4)
+ setSequenceAndDraw(2, kFightSequenceType2);
+ }
+ break;
+ }
+}
+
+void FighterOpponentIvo::update() {
+ if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) {
+
+ if (_opponent->getField34() >= 2) {
+ switch (rnd(5)) {
+ default:
+ break;
+
+ case 0:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 1:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+
+ case 2:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+
+ case 3:
+ setSequenceAndDraw(0, kFightSequenceType2);
+ setSequenceAndDraw(1, kFightSequenceType2);
+ break;
+
+ case 4:
+ setSequenceAndDraw(0, kFightSequenceType1);
+ setSequenceAndDraw(1, kFightSequenceType2);
+ break;
+ }
+ }
+
+ // Update field_38
+ _field_38 = 3 * _countdown + (int32)rnd(10);
+ }
+
+ if (_frame && checkFrame(2)) {
+
+ if (_opponent->getCountdown() <= 0) {
+ setSequenceAndDraw(7, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(8, kFightSequenceType1);
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+
+ _opponent->handleAction(kFightActionWin);
+
+ return;
+ }
+
+ if (_sequenceIndex == 1 || _sequenceIndex == 2)
+ _opponent->handleAction((FightAction)_sequenceIndex);
+ }
+
+ Fighter::update();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/fight/fighter_ivo.h b/engines/lastexpress/fight/fighter_ivo.h
new file mode 100644
index 0000000000..ca54fea904
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_ivo.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 LASTEXPRESS_FIGHTER_IVO_H
+#define LASTEXPRESS_FIGHTER_IVO_H
+
+#include "lastexpress/fight/fighter.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class FighterPlayerIvo : public Fighter {
+public:
+ FighterPlayerIvo(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+ virtual bool canInteract(FightAction action = kFightActionNone);
+};
+
+class FighterOpponentIvo : public Opponent {
+public:
+ FighterOpponentIvo(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FIGHTER_IVO_H
diff --git a/engines/lastexpress/fight/fighter_milos.cpp b/engines/lastexpress/fight/fighter_milos.cpp
new file mode 100644
index 0000000000..9f8e726165
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_milos.cpp
@@ -0,0 +1,222 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/fight/fighter_milos.h"
+
+#include "lastexpress/data/cursor.h"
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// Player
+//////////////////////////////////////////////////////////////////////////
+FighterPlayerMilos::FighterPlayerMilos(LastExpressEngine *engine) : Fighter(engine) {
+ _sequences.push_back(loadSequence("2001cr.seq"));
+ _sequences.push_back(loadSequence("2001cdl.seq"));
+ _sequences.push_back(loadSequence("2001cdr.seq"));
+ _sequences.push_back(loadSequence("2001cdm.seq"));
+ _sequences.push_back(loadSequence("2001csgr.seq"));
+ _sequences.push_back(loadSequence("2001csgl.seq"));
+ _sequences.push_back(loadSequence("2001dbk.seq"));
+}
+
+void FighterPlayerMilos::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ Fighter::handleAction(action);
+ return;
+
+ case kFightAction1:
+ if (_sequenceIndex != 1 || checkFrame(4)) {
+ setSequenceAndDraw(6, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(3, kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction2:
+ if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) {
+ setSequenceAndDraw(6, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(4, kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction128:
+ if (_sequenceIndex != 1 || checkFrame(4) || _opponent->getSequenceIndex() != 1) {
+ switch (_opponent->getSequenceIndex()) {
+ default:
+ setSequenceAndDraw(rnd(3) + 1, kFightSequenceType0);
+ break;
+
+ case 1:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 2:
+ setSequenceAndDraw(3, kFightSequenceType0);
+ break;
+ }
+ } else {
+ setSequenceAndDraw(4, kFightSequenceType1);
+ update();
+ }
+ break;
+ }
+}
+
+void FighterPlayerMilos::update() {
+ if (_frame && checkFrame(2)) {
+
+ // Draw sequences
+ if (_opponent->getCountdown() <= 0) {
+ setSequenceAndDraw(5, kFightSequenceType1);
+ _opponent->setSequenceAndDraw(6, kFightSequenceType1);
+
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ getSound()->playSound(kEntityTrain, "MUS029", kFlagDefault);
+
+ handleAction(kFightActionWin);
+ }
+
+ if (_sequenceIndex == 4) {
+ _opponent->handleAction(kFightAction4);
+ _fight->setEndType(Fight::kFightEndLost);
+ }
+ }
+
+ Fighter::update();
+}
+
+bool FighterPlayerMilos::canInteract(FightAction action) {
+ if (action != kFightAction128
+ || _sequenceIndex != 1
+ || !_frame
+ || checkFrame(4)
+ || _opponent->getSequenceIndex() != 1) {
+ return Fighter::canInteract();
+ }
+
+ _engine->getCursor()->setStyle(kCursorHand);
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Opponent
+//////////////////////////////////////////////////////////////////////////
+FighterOpponentMilos::FighterOpponentMilos(LastExpressEngine *engine) : Opponent(engine) {
+ _sequences.push_back(loadSequence("2001or.seq"));
+ _sequences.push_back(loadSequence("2001oal.seq"));
+ _sequences.push_back(loadSequence("2001oam.seq"));
+ _sequences.push_back(loadSequence("2001okl.seq"));
+ _sequences.push_back(loadSequence("2001okm.seq"));
+ _sequences.push_back(loadSequence("2001dbk.seq"));
+ _sequences.push_back(loadSequence("2001wbk.seq"));
+
+ getSound()->playSound(kEntityTables0, "MUS027", kFlagDefault);
+
+ _field_38 = 35;
+}
+
+void FighterOpponentMilos::handleAction(FightAction action) {
+ if (action == kFightAction4) {
+ setSequenceAndDraw(5, kFightSequenceType1);
+ _opponent->handleAction(kFightAction103);
+ } else {
+ if (action != kFightAction131)
+ Fighter::handleAction(action);
+ }
+}
+
+void FighterOpponentMilos::update() {
+ if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) {
+
+ if (_opponent->getField34() >= 2) {
+ switch (rnd(5)) {
+ default:
+ break;
+
+ case 0:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 1:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+
+ case 2:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType1);
+ break;
+
+ case 3:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+
+ case 4:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(1, kFightSequenceType2);
+ break;
+ }
+ } else {
+ setSequenceAndDraw(2, kFightSequenceType0);
+ }
+
+ // Update field_38
+ if (_opponent->getField34() < 5)
+ _field_38 = 6 * (5 - _opponent->getField34());
+ else
+ _field_38 = 0;
+ }
+
+ if (_frame && checkFrame(2)) {
+ if (_sequenceIndex == 1 || _sequenceIndex == 2)
+ _opponent->handleAction((FightAction)_sequenceIndex);
+
+ if (_opponent->getCountdown() <= 0) {
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ handleAction(kFightActionLost);
+ }
+ }
+
+ Fighter::update();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/fight/fighter_milos.h b/engines/lastexpress/fight/fighter_milos.h
new file mode 100644
index 0000000000..2126dd1838
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_milos.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 LASTEXPRESS_FIGHTER_MILOS_H
+#define LASTEXPRESS_FIGHTER_MILOS_H
+
+#include "lastexpress/fight/fighter.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class FighterPlayerMilos : public Fighter {
+public:
+ FighterPlayerMilos(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+ virtual bool canInteract(FightAction action = kFightActionNone);
+};
+
+class FighterOpponentMilos : public Opponent {
+public:
+ FighterOpponentMilos(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FIGHTER_MILOS_H
diff --git a/engines/lastexpress/fight/fighter_salko.cpp b/engines/lastexpress/fight/fighter_salko.cpp
new file mode 100644
index 0000000000..1082674235
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_salko.cpp
@@ -0,0 +1,202 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/fight/fighter_salko.h"
+
+#include "lastexpress/data/cursor.h"
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// Player
+//////////////////////////////////////////////////////////////////////////
+FighterPlayerSalko::FighterPlayerSalko(LastExpressEngine *engine) : Fighter(engine) {
+ _sequences.push_back(loadSequence("2004cr.seq"));
+ _sequences.push_back(loadSequence("2004cdr.seq"));
+ _sequences.push_back(loadSequence("2004chj.seq"));
+ _sequences.push_back(loadSequence("2004bk.seq"));
+
+ _countdown = 2;
+}
+
+void FighterPlayerSalko::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ Fighter::handleAction(action);
+ return;
+
+ case kFightAction1:
+ case kFightAction2:
+ if (_sequenceIndex != 1 && checkFrame(4)) {
+ _field_34 = 0;
+
+ setSequenceAndDraw(3, kFightSequenceType1);
+ _opponent->setSequenceAndDraw((action == kFightAction1 ? 3 : 4), kFightSequenceType1);
+
+ _opponent->handleAction(kFightAction103);
+
+ if (action == kFightAction2)
+ _countdown= 0;
+
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction5:
+ if (_sequenceIndex != 3) {
+ _opponent->handleAction(kFightAction103);
+ update();
+ }
+ break;
+
+ case kFightAction128:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ _field_34 = 0;
+ break;
+
+ case kFightAction131:
+ setSequenceAndDraw(2, (_sequenceIndex ? kFightSequenceType2 : kFightSequenceType0));
+ break;
+ }
+}
+
+void FighterPlayerSalko::update() {
+ Fighter::update();
+
+ // The original doesn't check for currentSequence2 != NULL (might not happen when everything is working properly, but crashes with our current implementation)
+ if (_frame && checkFrame(2)) {
+
+ if (_opponent->getCountdown() <= 0) {
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ _fight->bailout(Fight::kFightEndWin);
+
+ return;
+ }
+
+ if (_sequenceIndex == 2)
+ _opponent->handleAction(kFightAction2);
+ }
+}
+
+bool FighterPlayerSalko::canInteract(FightAction action) {
+ if (action == kFightAction131) {
+ if (_sequenceIndex == 1) {
+ if (_opponent->getCountdown() <= 0)
+ _engine->getCursor()->setStyle(kCursorHand);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ return Fighter::canInteract();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Opponent
+//////////////////////////////////////////////////////////////////////////
+FighterOpponentSalko::FighterOpponentSalko(LastExpressEngine *engine) : Opponent(engine) {
+ _sequences.push_back(loadSequence("2004or.seq"));
+ _sequences.push_back(loadSequence("2004oam.seq"));
+ _sequences.push_back(loadSequence("2004oar.seq"));
+ _sequences.push_back(loadSequence("2004okr.seq"));
+ _sequences.push_back(loadSequence("2004ohm.seq"));
+ _sequences.push_back(loadSequence("blank.seq"));
+
+ getSound()->playSound(kEntityTables0, "MUS035", kFlagDefault);
+
+ _countdown = 3;
+ _field_38 = 30;
+}
+
+void FighterOpponentSalko::handleAction(FightAction action) {
+ if (action == kFightAction2) {
+ setSequenceAndDraw(5, kFightSequenceType1);
+ _opponent->handleAction(kFightAction103);
+ } else {
+ Fighter::handleAction(action);
+ }
+}
+
+void FighterOpponentSalko::update() {
+ if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) {
+
+ switch (rnd(5)) {
+ default:
+ break;
+
+ case 0:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 1:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+
+ case 2:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+
+ case 3:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ setSequenceAndDraw(1, kFightSequenceType2);
+ break;
+
+ case 4:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(1, kFightSequenceType2);
+ break;
+ }
+
+ // Update field_38
+ _field_38 = 4 * _countdown;
+ }
+
+ if (_frame && checkFrame(2)) {
+ if (_opponent->getCountdown() <= 0) {
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ _fight->bailout(Fight::kFightEndLost);
+
+ // Stop processing
+ return;
+ }
+
+ if (_sequenceIndex == 1 || _sequenceIndex == 2)
+ _opponent->handleAction((FightAction)_sequenceIndex);
+ }
+
+ Fighter::update();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/fight/fighter_salko.h b/engines/lastexpress/fight/fighter_salko.h
new file mode 100644
index 0000000000..0a2a615867
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_salko.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 LASTEXPRESS_FIGHTER_SALKO_H
+#define LASTEXPRESS_FIGHTER_SALKO_H
+
+#include "lastexpress/fight/fighter.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class FighterPlayerSalko : public Fighter {
+public:
+ FighterPlayerSalko(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+ virtual bool canInteract(FightAction action = kFightActionNone);
+};
+
+class FighterOpponentSalko : public Opponent {
+public:
+ FighterOpponentSalko(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FIGHTER_SALKO_H
diff --git a/engines/lastexpress/fight/fighter_vesna.cpp b/engines/lastexpress/fight/fighter_vesna.cpp
new file mode 100644
index 0000000000..02aaa1c16c
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_vesna.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 "lastexpress/fight/fighter_vesna.h"
+
+#include "lastexpress/data/cursor.h"
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// Player
+//////////////////////////////////////////////////////////////////////////
+FighterPlayerVesna::FighterPlayerVesna(LastExpressEngine *engine) : Fighter(engine) {
+ _sequences.push_back(loadSequence("2005cr.seq"));
+ _sequences.push_back(loadSequence("2005cdr.seq"));
+ _sequences.push_back(loadSequence("2005cbr.seq"));
+ _sequences.push_back(loadSequence("2005bk.seq"));
+ _sequences.push_back(loadSequence("2005cdm1.seq"));
+ _sequences.push_back(loadSequence("2005chl.seq"));
+}
+
+void FighterPlayerVesna::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ Fighter::handleAction(action);
+ return;
+
+ case kFightAction1:
+ if (_sequenceIndex != 1) {
+ _opponent->handleAction(kFightAction103);
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction2:
+ if (_sequenceIndex != 2) {
+ _opponent->handleAction(kFightAction103);
+ update();
+ } else {
+ _field_34++;
+ }
+ break;
+
+ case kFightAction5:
+ if (_sequenceIndex != 3) {
+ _opponent->handleAction(kFightAction103);
+ update();
+ }
+ break;
+
+ case kFightAction128:
+ if (_sequenceIndex == 1 && _opponent->getSequenceIndex() == 1 && checkFrame(4)) {
+ setSequenceAndDraw(5, kFightSequenceType1);
+ } else {
+ setSequenceAndDraw((_opponent->getSequenceIndex() == 5) ? 3 : 1, kFightSequenceType0);
+ }
+ break;
+
+ case kFightAction132:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+ }
+
+ if (_field_34 > 10) {
+ _opponent->setSequenceAndDraw(5, kFightSequenceType2);
+ _opponent->setCountdown(1);
+ _field_34 = 0;
+ }
+}
+
+void FighterPlayerVesna::update() {
+ if (_frame && checkFrame(2)) {
+
+ if (_sequenceIndex == 3)
+ _opponent->handleAction(kFightAction3);
+
+ if (_opponent->getCountdown() <= 0) {
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+ _fight->bailout(Fight::kFightEndWin);
+ return;
+ }
+
+ if (_sequenceIndex == 5)
+ _opponent->handleAction(kFightAction5);
+ }
+
+ Fighter::update();
+}
+
+bool FighterPlayerVesna::canInteract(FightAction action) {
+ if (action != kFightAction128)
+ return Fighter::canInteract();
+
+ if (_sequenceIndex != 1) {
+
+ if (_opponent->getSequenceIndex() == 5) {
+ _engine->getCursor()->setStyle(kCursorDown);
+ return true;
+ }
+
+ return Fighter::canInteract();
+ }
+
+ if (_opponent->getSequenceIndex() == 1 && checkFrame(4)) {
+ _engine->getCursor()->setStyle(kCursorPunchLeft);
+ return true;
+ }
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Opponent
+//////////////////////////////////////////////////////////////////////////
+FighterOpponentVesna::FighterOpponentVesna(LastExpressEngine *engine) : Opponent(engine) {
+ _sequences.push_back(loadSequence("2005or.seq"));
+ _sequences.push_back(loadSequence("2005oam.seq"));
+ _sequences.push_back(loadSequence("2005oar.seq"));
+ _sequences.push_back(loadSequence("2005okml.seq"));
+ _sequences.push_back(loadSequence("2005okr.seq"));
+ _sequences.push_back(loadSequence("2005odm1.seq"));
+ _sequences.push_back(loadSequence("2005csbm.seq"));
+ _sequences.push_back(loadSequence("2005oam4.seq"));
+
+ getSound()->playSound(kEntityTables0, "MUS038", kFlagDefault);
+
+ _countdown = 4;
+ _field_38 = 30;
+}
+
+void FighterOpponentVesna::handleAction(FightAction action) {
+ switch (action) {
+ default:
+ Fighter::handleAction(action);
+ break;
+
+ case kFightAction3:
+ _opponent->handleAction(kFightAction103);
+ break;
+
+ case kFightAction5:
+ setSequenceAndDraw(7, kFightSequenceType1);
+ _opponent->handleAction(kFightAction103);
+ if (_countdown <= 1)
+ _countdown = 1;
+ break;
+
+ case kFightAction131:
+ break;
+ }
+}
+
+void FighterOpponentVesna::update() {
+ if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) {
+
+ if (_opponent->getField34() == 1) {
+ setSequenceAndDraw(2, kFightSequenceType0);
+ } else {
+ switch (rnd(6)) {
+ default:
+ break;
+
+ case 0:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ break;
+
+ case 1:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(1, kFightSequenceType2);
+ break;
+
+ case 2:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ break;
+
+ case 3:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+
+ case 4:
+ setSequenceAndDraw(1, kFightSequenceType0);
+ setSequenceAndDraw(2, kFightSequenceType2);
+ break;
+
+ case 5:
+ setSequenceAndDraw(2, kFightSequenceType0);
+ setSequenceAndDraw(1, kFightSequenceType2);
+ break;
+ }
+ }
+
+ // Update field_38
+ _field_38 = 4 * _countdown;
+ }
+
+ if (_frame && checkFrame(2)) {
+ if (_sequenceIndex == 1 || _sequenceIndex == 2 || _sequenceIndex == 5)
+ _opponent->handleAction((FightAction)_sequenceIndex);
+
+ if (_opponent->getCountdown() <= 0) {
+
+ switch (_sequenceIndex) {
+ default:
+ break;
+
+ case 1:
+ setSequenceAndDraw(3, kFightSequenceType1);
+ break;
+
+ case 2:
+ setSequenceAndDraw(4, kFightSequenceType1);
+ break;
+
+ case 5:
+ setSequenceAndDraw(6, kFightSequenceType1);
+ break;
+ }
+
+ _opponent->setSequenceAndDraw(4, kFightSequenceType1);
+
+ handleAction(kFightActionLost);
+ _opponent->update();
+ Fighter::update();
+
+ getSoundQueue()->removeFromQueue(kEntityTables0);
+
+ // Stop processing
+ return;
+ }
+ }
+
+ Fighter::update();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/fight/fighter_vesna.h b/engines/lastexpress/fight/fighter_vesna.h
new file mode 100644
index 0000000000..5c8ec855ae
--- /dev/null
+++ b/engines/lastexpress/fight/fighter_vesna.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 LASTEXPRESS_FIGHTER_VESNA_H
+#define LASTEXPRESS_FIGHTER_VESNA_H
+
+#include "lastexpress/fight/fighter.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class FighterPlayerVesna : public Fighter {
+public:
+ FighterPlayerVesna(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+ virtual bool canInteract(FightAction action = kFightActionNone);
+};
+
+class FighterOpponentVesna : public Opponent {
+public:
+ FighterOpponentVesna(LastExpressEngine *engine);
+
+ virtual void handleAction(FightAction action);
+ virtual void update();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FIGHTER_VESNA_H
diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp
index 7540d18ed8..2ef4c20d70 100644
--- a/engines/lastexpress/game/action.cpp
+++ b/engines/lastexpress/game/action.cpp
@@ -39,9 +39,11 @@
#include "lastexpress/game/savegame.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
#include "lastexpress/resource.h"
@@ -405,7 +407,7 @@ SceneIndex Action::processHotspot(const SceneHotspot &hotspot) {
//////////////////////////////////////////////////////////////////////////
// Action 0
IMPLEMENT_ACTION(dummy)
- warning("Action::action_dummy: Dummy action function called (hotspot action: %d)!", hotspot.action);
+ warning("[Action::action_dummy] Dummy action function called (hotspot action: %d)", hotspot.action);
return kSceneInvalid;
}
@@ -453,7 +455,7 @@ IMPLEMENT_ACTION(savePoint)
IMPLEMENT_ACTION(playSound)
// Check that the file is not already buffered
- if (hotspot.param2 || !getSound()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true))
+ if (hotspot.param2 || !getSoundQueue()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true))
getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2);
return kSceneInvalid;
@@ -465,8 +467,8 @@ IMPLEMENT_ACTION(playMusic)
// Check that the file is not already buffered
Common::String filename = Common::String::format("MUS%03d", hotspot.param1);
- if (!getSound()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5))
- getSound()->playSound(kEntityPlayer, filename, SoundManager::kFlagDefault, hotspot.param2);
+ if (!getSoundQueue()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5))
+ getSound()->playSound(kEntityPlayer, filename, kFlagDefault, hotspot.param2);
return kSceneInvalid;
}
@@ -481,7 +483,7 @@ IMPLEMENT_ACTION(knock)
if (getObjects()->get(object).entity) {
getSavePoints()->push(kEntityPlayer, getObjects()->get(object).entity, kActionKnock, object);
} else {
- if (!getSound()->isBuffered("LIB012", true))
+ if (!getSoundQueue()->isBuffered("LIB012", true))
getSound()->playSoundEvent(kEntityPlayer, 12);
}
@@ -516,7 +518,7 @@ IMPLEMENT_ACTION(compartment)
&& (compartment != kObjectCompartment1
|| !getInventory()->hasItem(kItemKey)
|| (getInventory()->getSelectedItem() != kItemFirebird && getInventory()->getSelectedItem() != kItemBriefcase)))) {
- if (!getSound()->isBuffered("LIB13"))
+ if (!getSoundQueue()->isBuffered("LIB13"))
getSound()->playSoundEvent(kEntityPlayer, 13);
// Stop processing further
@@ -621,7 +623,7 @@ IMPLEMENT_ACTION(updateObjetLocation2)
getObjects()->updateLocation2(object, location);
- if (object != kObject112 || getSound()->isBuffered("LIB096")) {
+ if (object != kObject112 || getSoundQueue()->isBuffered("LIB096")) {
if (object == 1)
getSound()->playSoundEvent(kEntityPlayer, 73);
} else {
@@ -805,8 +807,8 @@ IMPLEMENT_ACTION(enterCompartment)
getSound()->playSoundEvent(kEntityPlayer, 14);
getSound()->playSoundEvent(kEntityPlayer, 15, 22);
- if (getProgress().field_78 && !getSound()->isBuffered("MUS003")) {
- getSound()->playSound(kEntityPlayer, "MUS003", SoundManager::kFlagDefault);
+ if (getProgress().field_78 && !getSoundQueue()->isBuffered("MUS003")) {
+ getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault);
getProgress().field_78 = 0;
}
@@ -1083,8 +1085,8 @@ IMPLEMENT_ACTION(25)
break;
case 2:
- if (!getSound()->isBuffered("MUS021"))
- getSound()->playSound(kEntityPlayer, "MUS021", SoundManager::kFlagDefault);
+ if (!getSoundQueue()->isBuffered("MUS021"))
+ getSound()->playSound(kEntityPlayer, "MUS021", kFlagDefault);
break;
case 3:
@@ -1134,7 +1136,7 @@ IMPLEMENT_ACTION(26)
//////////////////////////////////////////////////////////////////////////
// Action 27
IMPLEMENT_ACTION(27)
- if (!getSound()->isBuffered("LIB031", true))
+ if (!getSoundQueue()->isBuffered("LIB031", true))
getSound()->playSoundEvent(kEntityPlayer, 31);
switch (getEntityData(kEntityPlayer)->car) {
@@ -1182,8 +1184,8 @@ IMPLEMENT_ACTION(29)
getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2);
Common::String filename = Common::String::format("MUS%03d", hotspot.param3);
- if (!getSound()->isBuffered(filename))
- getSound()->playSound(kEntityPlayer, filename, SoundManager::kFlagDefault);
+ if (!getSoundQueue()->isBuffered(filename))
+ getSound()->playSound(kEntityPlayer, filename, kFlagDefault);
return kSceneInvalid;
}
@@ -1345,7 +1347,7 @@ IMPLEMENT_ACTION(openBed)
//////////////////////////////////////////////////////////////////////////
// Action 37
IMPLEMENT_ACTION(dialog)
- getSound()->playDialog(kEntityTables4, (EntityIndex)hotspot.param1, SoundManager::kFlagDefault, 0);
+ getSound()->playDialog(kEntityTables4, (EntityIndex)hotspot.param1, kFlagDefault, 0);
return kSceneInvalid;
}
@@ -1354,8 +1356,8 @@ IMPLEMENT_ACTION(dialog)
// Action 38
IMPLEMENT_ACTION(eggBox)
getSound()->playSoundEvent(kEntityPlayer, 43);
- if (getProgress().field_7C && !getSound()->isBuffered("MUS003")) {
- getSound()->playSound(kEntityPlayer, "MUS003", SoundManager::kFlagDefault);
+ if (getProgress().field_7C && !getSoundQueue()->isBuffered("MUS003")) {
+ getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault);
getProgress().field_7C = 0;
}
@@ -1366,8 +1368,8 @@ IMPLEMENT_ACTION(eggBox)
// Action 39
IMPLEMENT_ACTION(39)
getSound()->playSoundEvent(kEntityPlayer, 24);
- if (getProgress().field_80 && !getSound()->isBuffered("MUS003")) {
- getSound()->playSound(kEntityPlayer, "MUS003", SoundManager::kFlagDefault);
+ if (getProgress().field_80 && !getSoundQueue()->isBuffered("MUS003")) {
+ getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault);
getProgress().field_80 = 0;
}
@@ -1408,8 +1410,8 @@ IMPLEMENT_ACTION(playMusicChapter)
if (id) {
Common::String filename = Common::String::format("MUS%03d", id);
- if (!getSound()->isBuffered(filename))
- getSound()->playSound(kEntityPlayer, filename, SoundManager::kFlagDefault);
+ if (!getSoundQueue()->isBuffered(filename))
+ getSound()->playSound(kEntityPlayer, filename, kFlagDefault);
}
return kSceneInvalid;
@@ -1440,8 +1442,8 @@ IMPLEMENT_ACTION(playMusicChapterSetupTrain)
Common::String filename = Common::String::format("MUS%03d", hotspot.param1);
- if (!getSound()->isBuffered(filename) && hotspot.param3 & id) {
- getSound()->playSound(kEntityPlayer, filename, SoundManager::kFlagDefault);
+ if (!getSoundQueue()->isBuffered(filename) && hotspot.param3 & id) {
+ getSound()->playSound(kEntityPlayer, filename, kFlagDefault);
getSavePoints()->call(kEntityPlayer, kEntityTrain, kAction203863200, filename.c_str());
getSavePoints()->push(kEntityPlayer, kEntityTrain, kAction222746496, hotspot.param2);
@@ -1612,7 +1614,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
if (doPlaySound)
playCompartmentSoundEvents(object);
- if (!getSound()->isBuffered(kEntityMertens))
+ if (!getSoundQueue()->isBuffered(kEntityMertens))
getSound()->playWarningCompartment(kEntityMertens, object);
getSavePoints()->push(kEntityPlayer, kEntityMertens, kAction305159806);
@@ -1628,7 +1630,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
if (doPlaySound)
playCompartmentSoundEvents(object);
- if (!getSound()->isBuffered(kEntityMertens))
+ if (!getSoundQueue()->isBuffered(kEntityMertens))
getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A");
if (doLoadScene)
@@ -1640,7 +1642,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
if (doPlaySound)
playCompartmentSoundEvents(object);
- if (!getSound()->isBuffered(kEntityMertens))
+ if (!getSoundQueue()->isBuffered(kEntityMertens))
getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A");
if (doLoadScene)
@@ -1667,7 +1669,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
if (doPlaySound)
playCompartmentSoundEvents(object);
- if (!getSound()->isBuffered(kEntityCoudert))
+ if (!getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playWarningCompartment(kEntityCoudert, object);
getSavePoints()->push(kEntityPlayer, kEntityCoudert, kAction305159806);
@@ -1684,7 +1686,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
if (doPlaySound)
playCompartmentSoundEvents(object);
- if (!getSound()->isBuffered(kEntityCoudert))
+ if (!getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A");
if (doLoadScene)
@@ -1699,7 +1701,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
if (doPlaySound)
playCompartmentSoundEvents(object);
- if (!getSound()->isBuffered(kEntityCoudert))
+ if (!getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A");
if (doLoadScene)
@@ -1908,7 +1910,7 @@ LABEL_KEY:
// Play an animation and add delta time to global game time
void Action::playAnimation(EventIndex index, bool debugMode) const {
if (index >= _animationListSize)
- error("Action::playAnimation: invalid event index (value=%i, max=%i)", index, _animationListSize);
+ error("[Action::playAnimation] Invalid event index (value=%i, max=%i)", index, _animationListSize);
// In debug mode, just show the animation
if (debugMode) {
@@ -1930,8 +1932,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const {
if (!getFlags()->mouseRightClick) {
if (getGlobalTimer()) {
- if (getSound()->isBuffered("TIMER")) {
- getSound()->processEntry("TIMER");
+ if (getSoundQueue()->isBuffered("TIMER")) {
+ getSoundQueue()->processEntry("TIMER");
setGlobalTimer(105);
}
}
@@ -1948,8 +1950,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const {
if (animation.load(getArchive(Common::String(_animationList[index].filename) + ".nis") , processSound ? Animation::kFlagDefault : Animation::kFlagProcess))
animation.play();
- if (getSound()->isBuffered("TIMER"))
- getSound()->removeFromQueue("TIMER");
+ if (getSoundQueue()->isBuffered("TIMER"))
+ getSoundQueue()->removeFromQueue("TIMER");
}
// Show cursor
diff --git a/engines/lastexpress/game/beetle.cpp b/engines/lastexpress/game/beetle.cpp
index cb6f0a3306..ab707ddae9 100644
--- a/engines/lastexpress/game/beetle.cpp
+++ b/engines/lastexpress/game/beetle.cpp
@@ -131,7 +131,7 @@ bool Beetle::isLoaded() const {
bool Beetle::catchBeetle() {
if (!_data)
- error("Beetle::catchBeetle: sequences have not been loaded!");
+ error("[Beetle::catchBeetle] Sequences have not been loaded");
if (getInventory()->getSelectedItem() == kItemMatchBox
&& getInventory()->hasItem(kItemMatch)
@@ -148,14 +148,14 @@ bool Beetle::catchBeetle() {
bool Beetle::isCatchable() const {
if (!_data)
- error("Beetle::isCatchable: sequences have not been loaded!");
+ error("[Beetle::isCatchable] Sequences have not been loaded");
return (_data->indexes[_data->offset] >= 30);
}
void Beetle::update() {
if (!_data)
- error("Beetle::update: sequences have not been loaded!");
+ error("[Beetle::update] Sequences have not been loaded");
if (!_data->isLoaded)
return;
@@ -194,7 +194,7 @@ void Beetle::update() {
void Beetle::drawUpdate() {
if (!_data)
- error("Beetle::drawUpdate: sequences have not been loaded!");
+ error("[Beetle::drawUpdate] Sequences have not been loaded");
if (_data->frame != NULL) {
getScenes()->setCoordinates(_data->frame);
@@ -366,7 +366,7 @@ void Beetle::drawUpdate() {
void Beetle::move() {
if (!_data)
- error("Beetle::move: sequences have not been loaded!");
+ error("[Beetle::move] Sequences have not been loaded");
if (_data->indexes[_data->offset] >= 24 && _data->indexes[_data->offset] <= 29)
return;
@@ -444,7 +444,7 @@ update_data:
// Update the beetle sequence to show the correct frames in the correct place
void Beetle::updateFrame(SequenceFrame *frame) const {
if (!_data)
- error("Beetle::updateSequence: sequences have not been loaded!");
+ error("[Beetle::updateFrame] Sequences have not been loaded");
if (!frame)
return;
@@ -459,7 +459,7 @@ void Beetle::updateFrame(SequenceFrame *frame) const {
void Beetle::updateData(uint32 index) {
if (!_data)
- error("Beetle::updateData: sequences have not been loaded!");
+ error("[Beetle::updateData] Sequences have not been loaded");
if (!_data->isLoaded)
return;
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index 513ad114b0..f6bb2030f0 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -68,9 +68,11 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/graphics.h"
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -200,7 +202,7 @@ Entity *Entities::get(EntityIndex entity) {
assert((uint)entity < _entities.size());
if (entity == kEntityPlayer)
- error("Cannot get entity for index == 0!");
+ error("[Entities::get] Cannot get entity for kEntityPlayer");
return _entities[entity];
}
@@ -218,24 +220,24 @@ int Entities::getPosition(CarIndex car, Position position) const {
int index = 100 * car + position;
if (car > 10)
- error("Entities::getPosition: trying to access an invalid car (was: %d, valid:0-9)", car);
+ error("[Entities::getPosition] Trying to access an invalid car (was: %d, valid:0-9)", car);
if (position > 100)
- error("Entities::getPosition: trying to access an invalid position (was: %d, valid:0-100)", position);
+ error("[Entities::getPosition] Trying to access an invalid position (was: %d, valid:0-100)", position);
return _positions[index];
}
int Entities::getCompartments(int index) const {
if (index >= _compartmentsCount)
- error("Entities::getCompartments: trying to access an invalid compartment (was: %d, valid:0-15)", index);
+ error("[Entities::getCompartments] Trying to access an invalid compartment (was: %d, valid:0-15)", index);
return _compartments[index];
}
int Entities::getCompartments1(int index) const {
if (index >= _compartmentsCount)
- error("Entities::getCompartments: trying to access an invalid compartment (was: %d, valid:0-15)", index);
+ error("[Entities::getCompartments] Trying to access an invalid compartment (was: %d, valid:0-15)", index);
return _compartments1[index];
}
@@ -299,7 +301,7 @@ void Entities::setupChapter(ChapterIndex chapter) {
memset(&_compartments1, 0, sizeof(_compartments1));
memset(&_positions, 0, sizeof(_positions));
- getSound()->resetQueue(SoundManager::kSoundType13);
+ getSoundQueue()->resetQueue(kSoundType13);
}
// we skip the header when doing entity setup
@@ -369,8 +371,8 @@ void Entities::resetState(EntityIndex entityIndex) {
getData(entityIndex)->currentCall = 0;
getData(entityIndex)->inventoryItem = kItemNone;
- if (getSound()->isBuffered(entityIndex))
- getSound()->removeFromQueue(entityIndex);
+ if (getSoundQueue()->isBuffered(entityIndex))
+ getSoundQueue()->removeFromQueue(entityIndex);
clearSequences(entityIndex);
@@ -1780,7 +1782,7 @@ void Entities::enterCompartment(EntityIndex entity, ObjectIndex compartment, boo
// Update compartments
int index = (compartment < 32 ? compartment - 1 : compartment - 24);
if (index >= 16)
- error("Entities::exitCompartment: invalid compartment index!");
+ error("[Entities::enterCompartment] Invalid compartment index");
if (useCompartment1)
_compartments1[index] |= STORE_VALUE(entity);
@@ -1866,7 +1868,7 @@ void Entities::exitCompartment(EntityIndex entity, ObjectIndex compartment, bool
// Update compartments
int index = (compartment < 32 ? compartment - 1 : compartment - 24);
if (index >= 16)
- error("Entities::exitCompartment: invalid compartment index!");
+ error("[Entities::exitCompartment] Invalid compartment index");
if (useCompartment1)
_compartments1[index] &= ~STORE_VALUE(entity);
@@ -2355,7 +2357,7 @@ bool Entities::changeCar(EntityData::EntityCallData *data, EntityIndex entity, C
if (data->car == newCar) {
if (isInGreenCarEntrance(kEntityPlayer)) {
getSound()->playSoundEvent(kEntityPlayer, 14);
- getSound()->excuseMe(entity, kEntityPlayer, SoundManager::kFlagDefault);
+ getSound()->excuseMe(entity, kEntityPlayer, kFlagDefault);
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 1);
getSound()->playSound(kEntityPlayer, "CAT1127A");
getSound()->playSoundEvent(kEntityPlayer, 15);
@@ -2374,7 +2376,7 @@ bool Entities::changeCar(EntityData::EntityCallData *data, EntityIndex entity, C
if (data->car == newCar) {
if (isInKronosCarEntrance(kEntityPlayer)) {
getSound()->playSoundEvent(kEntityPlayer, 14);
- getSound()->excuseMe(entity, kEntityPlayer, SoundManager::kFlagDefault);
+ getSound()->excuseMe(entity, kEntityPlayer, kFlagDefault);
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 62);
getSound()->playSound(kEntityPlayer, "CAT1127A");
getSound()->playSoundEvent(kEntityPlayer, 15);
diff --git a/engines/lastexpress/game/fight.cpp b/engines/lastexpress/game/fight.cpp
deleted file mode 100644
index ecc43bed2b..0000000000
--- a/engines/lastexpress/game/fight.cpp
+++ /dev/null
@@ -1,1583 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "lastexpress/game/fight.h"
-
-#include "lastexpress/data/cursor.h"
-#include "lastexpress/data/scene.h"
-#include "lastexpress/data/sequence.h"
-
-#include "lastexpress/game/entities.h"
-#include "lastexpress/game/inventory.h"
-#include "lastexpress/game/logic.h"
-#include "lastexpress/game/object.h"
-#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
-#include "lastexpress/game/state.h"
-
-#include "lastexpress/graphics.h"
-#include "lastexpress/helpers.h"
-#include "lastexpress/lastexpress.h"
-#include "lastexpress/resource.h"
-
-#include "common/func.h"
-
-namespace LastExpress {
-
-#define CALL_FUNCTION0(fighter, name) \
- (*fighter->name)(fighter)
-
-#define CALL_FUNCTION1(fighter, name, a) \
- (*fighter->name)(fighter, a)
-
-#define REGISTER_PLAYER_FUNCTIONS(name) \
- if (!_data) \
- error("Fight::load##namePlayer - invalid data!"); \
- _data->player->handleAction = new Common::Functor2Mem<Fighter *, FightAction, void, Fight>(this, &Fight::handleAction##name); \
- _data->player->update = new Common::Functor1Mem<Fighter *, void, Fight>(this, &Fight::update##name); \
- _data->player->canInteract = new Common::Functor2Mem<Fighter const *, FightAction, bool, Fight>(this, &Fight::canInteract##name);
-
-#define REGISTER_OPPONENT_FUNCTIONS(name) \
- if (!_data) \
- error("Fight::load##nameOpponent - invalid data!"); \
- _data->opponent->handleAction = new Common::Functor2Mem<Fighter *, FightAction, void, Fight>(this, &Fight::handleOpponentAction##name); \
- _data->opponent->update = new Common::Functor1Mem<Fighter *, void, Fight>(this, &Fight::updateOpponent##name); \
- _data->opponent->canInteract = new Common::Functor2Mem<Fighter const *, FightAction, bool, Fight>(this, &Fight::canInteract);
-
-#define CHECK_SEQUENCE2(fighter, value) \
- (fighter->frame->getInfo()->field_33 & value)
-
-Fight::Fight(LastExpressEngine *engine) : _engine(engine), _data(NULL), _endType(kFightEndLost), _state(0), _handleTimer(false) {}
-
-Fight::~Fight() {
- clearData();
- _data = NULL;
-
- // Zero passed pointers
- _engine = NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Events
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::eventMouse(const Common::Event &ev) {
- if (!_data || _data->index)
- return;
-
- // TODO move all the egg handling to inventory functions
-
- getFlags()->mouseLeftClick = false;
- getFlags()->shouldRedraw = false;
- getFlags()->mouseRightClick = false;
-
- if (ev.mouse.x < 608 || ev.mouse.y < 448 || ev.mouse.x >= 640 || ev.mouse.x >= 480) {
-
- // Handle right button click
- if (ev.type == Common::EVENT_RBUTTONUP) {
- getSound()->removeFromQueue(kEntityTables0);
- setStopped();
-
- getGlobalTimer() ? _state = 0 : ++_state;
-
- getFlags()->mouseRightClick = true;
- }
-
- if (_handleTimer) {
- // Timer expired => show with full brightness
- if (!getGlobalTimer())
- getInventory()->drawBlinkingEgg();
-
- _handleTimer = false;
- }
-
- // Check hotspots
- Scene *scene = getScenes()->get(getState()->scene);
- SceneHotspot *hotspot = NULL;
-
- if (!scene->checkHotSpot(ev.mouse, &hotspot)) {
- _engine->getCursor()->setStyle(kCursorNormal);
- } else {
- _engine->getCursor()->setStyle((CursorStyle)hotspot->cursor);
-
- // Call player function
- if (CALL_FUNCTION1(_data->player, canInteract, (FightAction)hotspot->action)) {
- if (ev.type == Common::EVENT_LBUTTONUP)
- CALL_FUNCTION1(_data->player, handleAction, (FightAction)hotspot->action);
- } else {
- _engine->getCursor()->setStyle(kCursorNormal);
- }
- }
- } else {
- // Handle clicks on menu icon
-
- if (!_handleTimer) {
- // Timer expired => show with full brightness
- if (!getGlobalTimer())
- getInventory()->drawBlinkingEgg();
-
- _handleTimer = true;
- }
-
- // Stop fight if clicked
- if (ev.type == Common::EVENT_LBUTTONUP) {
- _handleTimer = false;
- getSound()->removeFromQueue(kEntityTables0);
- bailout(kFightEndExit);
- }
-
- // Reset timer on right click
- if (ev.type == Common::EVENT_RBUTTONUP) {
- if (getGlobalTimer()) {
- if (getSound()->isBuffered("TIMER"))
- getSound()->removeFromQueue("TIMER");
-
- setGlobalTimer(900);
- }
- }
- }
-
- getFlags()->shouldRedraw = true;
-}
-
-void Fight::eventTick(const Common::Event &ev) {
- handleTick(ev, true);
-}
-
-void Fight::handleTick(const Common::Event &ev, bool isProcessing) {
- // TODO move all the egg handling to inventory functions
-
- // Blink egg
- if (getGlobalTimer()) {
- warning("Fight::handleMouseMove - egg blinking not implemented!");
- }
-
- if (!_data || _data->index)
- return;
-
- SceneHotspot *hotspot = NULL;
- if (!getScenes()->get(getState()->scene)->checkHotSpot(ev.mouse, &hotspot) || !CALL_FUNCTION1(_data->player, canInteract, (FightAction)hotspot->action)) {
- _engine->getCursor()->setStyle(kCursorNormal);
- } else {
- _engine->getCursor()->setStyle((CursorStyle)hotspot->cursor);
- }
-
- CALL_FUNCTION0(_data->player, update);
- CALL_FUNCTION0(_data->opponent, update);
-
- // Draw sequences
- if (!_data->isRunning)
- return;
-
- if (isProcessing)
- getScenes()->drawFrames(true);
-
- if (_data->index) {
- // Set next sequence name index
- _data->index--;
- _data->sequences[_data->index] = loadSequence(_data->names[_data->index]);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Setup
-//////////////////////////////////////////////////////////////////////////
-
-Fight::FightEndType Fight::setup(FightType type) {
- if (_data)
- error("Fight::setup - calling fight setup again while a fight is already in progress!");
-
- //////////////////////////////////////////////////////////////////////////
- // Prepare UI & state
- if (_state >= 5 && (type == kFightSalko || type == kFightVesna)) {
- _state = 0;
- return kFightEndWin;
- }
-
- getInventory()->showHourGlass();
- // TODO events function
- getFlags()->flag_0 = false;
- getFlags()->mouseRightClick = false;
- getEntities()->reset();
-
- // Compute scene to use
- SceneIndex sceneIndex;
- switch(type) {
- default:
- sceneIndex = kSceneFightDefault;
- break;
-
- case kFightMilos:
- sceneIndex = (getObjects()->get(kObjectCompartment1).location2 < kObjectLocation3) ? kSceneFightMilos : kSceneFightMilosBedOpened;
- break;
-
- case kFightAnna:
- sceneIndex = kSceneFightAnna;
- break;
-
- case kFightIvo:
- sceneIndex = kSceneFightIvo;
- break;
-
- case kFightSalko:
- sceneIndex = kSceneFightSalko;
- break;
-
- case kFightVesna:
- sceneIndex = kSceneFightVesna;
- break;
- }
-
- if (getFlags()->shouldRedraw) {
- getFlags()->shouldRedraw = false;
- askForRedraw();
- //redrawScreen();
- }
-
- // Load the scene object
- Scene *scene = getScenes()->get(sceneIndex);
-
- // Update game entities and state
- getEntityData(kEntityPlayer)->entityPosition = scene->entityPosition;
- getEntityData(kEntityPlayer)->location = scene->location;
-
- getState()->scene = sceneIndex;
-
- getFlags()->flag_3 = true;
-
- // Draw the scene
- _engine->getGraphicsManager()->draw(scene, GraphicsManager::kBackgroundC);
- // FIXME move to start of fight?
- askForRedraw();
- redrawScreen();
-
- //////////////////////////////////////////////////////////////////////////
- // Setup the fight
- _data = new FightData;
- loadData(type);
-
- // Show opponents & egg button
- Common::Event emptyEvent;
- handleTick(emptyEvent, false);
- getInventory()->drawEgg();
-
- // Start fight
- _endType = kFightEndLost;
- while (_data->isRunning) {
- if (_engine->handleEvents())
- continue;
-
- getSound()->updateQueue();
- }
-
- // Cleanup after fight is over
- clearData();
-
- return _endType;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Status
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::setStopped() {
- if (_data)
- _data->isRunning = false;
-}
-
-void Fight::bailout(FightEndType type) {
- _state = 0;
- _endType = type;
- setStopped();
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Cleanup
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::clearData() {
- if (!_data)
- return;
-
- // Clear data
- clearSequences(_data->player);
- clearSequences(_data->opponent);
-
- SAFE_DELETE(_data->player);
- SAFE_DELETE(_data->opponent);
-
- SAFE_DELETE(_data);
-
- _engine->restoreEventHandlers();
-}
-
-void Fight::clearSequences(Fighter *combatant) const {
- if (!combatant)
- return;
-
- // The original game resets the function pointers to default values, just before deleting the struct
- getScenes()->removeAndRedraw(&combatant->frame, false);
-
- // Free sequences
- for (int i = 0; i < (int)combatant->sequences.size(); i++)
- SAFE_DELETE(combatant->sequences[i]);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Drawing
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::setSequenceAndDraw(Fighter *combatant, uint32 sequenceIndex, FightSequenceType type) const {
- if (combatant->sequences.size() < sequenceIndex)
- return;
-
- switch (type) {
- default:
- break;
-
- case kFightSequenceType0:
- if (combatant->sequenceIndex)
- return;
-
- combatant->sequence = combatant->sequences[sequenceIndex];
- combatant->sequenceIndex = sequenceIndex;
- draw(combatant);
- break;
-
- case kFightSequenceType1:
- combatant->sequence = combatant->sequences[sequenceIndex];
- combatant->sequenceIndex = sequenceIndex;
- combatant->sequenceIndex2 = 0;
- draw(combatant);
- break;
-
- case kFightSequenceType2:
- combatant->sequenceIndex2 = sequenceIndex;
- break;
- }
-}
-
-void Fight::draw(Fighter *combatant) const {
- getScenes()->removeAndRedraw(&combatant->frame, false);
-
- combatant->frameIndex = 0;
- combatant->field_24 = 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Loading
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::loadData(FightType type) {
- if (!_data)
- error("Fight::loadData - invalid data!");
-
- switch (type) {
- default:
- break;
-
- case kFightMilos:
- loadMilosPlayer();
- loadMilosOpponent();
- break;
-
- case kFightAnna:
- loadAnnaPlayer();
- loadAnnaOpponent();
- break;
-
- case kFightIvo:
- loadIvoPlayer();
- loadIvoOpponent();
- break;
-
- case kFightSalko:
- loadSalkoPlayer();
- loadSalkoOpponent();
- break;
-
- case kFightVesna:
- loadVesnaPlayer();
- loadVesnaOpponent();
- break;
- }
-
- if (!_data->player || !_data->opponent)
- error("Fight::loadData - error loading fight data (type=%d)", type);
-
- //////////////////////////////////////////////////////////////////////////
- // Start running the fight
- _data->isRunning = true;
-
- if (_state < 5) {
- setSequenceAndDraw(_data->player, 0, kFightSequenceType0);
- setSequenceAndDraw(_data->opponent, 0, kFightSequenceType0);
- goto end_load;
- }
-
- switch(type) {
- default:
- break;
-
- case kFightMilos:
- _data->opponent->countdown = 1;
- setSequenceAndDraw(_data->player, 4, kFightSequenceType0);
- setSequenceAndDraw(_data->opponent, 0, kFightSequenceType0);
- break;
-
- case kFightIvo:
- _data->opponent->countdown = 1;
- setSequenceAndDraw(_data->player, 3, kFightSequenceType0);
- setSequenceAndDraw(_data->opponent, 6, kFightSequenceType0);
- break;
-
- case kFightVesna:
- _data->opponent->countdown = 1;
- setSequenceAndDraw(_data->player, 0, kFightSequenceType0);
- setSequenceAndDraw(_data->player, 3, kFightSequenceType2);
- setSequenceAndDraw(_data->opponent, 5, kFightSequenceType0);
- break;
- }
-
-end_load:
- // Setup event handlers
- _engine->backupEventHandlers();
- SET_EVENT_HANDLERS(Fight, this);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Shared
-//////////////////////////////////////////////////////////////////////////
-void Fight::processFighter(Fighter *fighter) {
- if (!_data)
- error("Fight::processFighter - invalid data!");
-
- if (!fighter->sequence) {
- if (fighter->frame) {
- getScenes()->removeFromQueue(fighter->frame);
- getScenes()->setCoordinates(fighter->frame);
- }
- SAFE_DELETE(fighter->frame);
- return;
- }
-
- if (fighter->sequence->count() <= fighter->frameIndex) {
- switch(fighter->action) {
- default:
- break;
-
- case kFightAction101:
- setSequenceAndDraw(fighter, fighter->sequenceIndex2, kFightSequenceType1);
- fighter->sequenceIndex2 = 0;
- break;
-
- case kFightActionResetFrame:
- fighter->frameIndex = 0;
- break;
-
- case kFightAction103:
- setSequenceAndDraw(fighter, 0, kFightSequenceType1);
- CALL_FUNCTION1(fighter, handleAction, kFightAction101);
- setSequenceAndDraw(fighter->opponent, 0, kFightSequenceType1);
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction101);
- CALL_FUNCTION0(fighter->opponent, update);
- break;
-
- case kFightActionWin:
- bailout(kFightEndWin);
- break;
-
- case kFightActionLost:
- bailout(kFightEndLost);
- break;
- }
- }
-
- if (_data->isRunning) {
-
- // Get the current sequence frame
- SequenceFrame *frame = new SequenceFrame(fighter->sequence, (uint16)fighter->frameIndex);
- frame->getInfo()->location = 1;
-
- if (fighter->frame == frame) {
- delete frame;
- return;
- }
-
- getSound()->playFightSound(frame->getInfo()->soundAction, frame->getInfo()->field_31);
-
- // Add current frame to queue and advance
- getScenes()->addToQueue(frame);
- fighter->frameIndex++;
-
- if (fighter->frame) {
- getScenes()->removeFromQueue(fighter->frame);
-
- if (!frame->getInfo()->field_2E)
- getScenes()->setCoordinates(fighter->frame);
- }
-
- // Replace by new frame
- delete fighter->frame;
- fighter->frame = frame;
- }
-}
-
-void Fight::handleAction(Fighter *fighter, FightAction action) {
- switch (action) {
- default:
- return;
-
- case kFightAction101:
- break;
-
- case kFightActionResetFrame:
- fighter->countdown--;
- break;
-
- case kFightAction103:
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightActionResetFrame);
- break;
-
- case kFightActionWin:
- _endType = kFightEndWin;
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightActionResetFrame);
- break;
-
- case kFightActionLost:
- _endType = kFightEndLost;
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightActionResetFrame);
- break;
- }
-
- // Update action
- fighter->action = action;
-}
-
-bool Fight::canInteract(Fighter const *fighter, FightAction /*= (FightAction)0*/ ) {
- return (fighter->action == kFightAction101 && !fighter->sequenceIndex);
-}
-
-void Fight::update(Fighter *fighter) {
-
- processFighter(fighter);
-
- if (fighter->frame)
- fighter->frame->getInfo()->location = (fighter->action == kFightActionResetFrame ? 2 : 0);
-}
-
-void Fight::updateOpponent(Fighter *fighter) {
-
- // This is an opponent struct!
- Opponent *opponent = (Opponent *)fighter;
-
- processFighter(opponent);
-
- if (opponent->field_38 && !opponent->sequenceIndex)
- opponent->field_38--;
-
- if (fighter->frame)
- fighter->frame->getInfo()->location = 1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Milos
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::loadMilosPlayer() {
- REGISTER_PLAYER_FUNCTIONS(Milos)
-
- _data->player->sequences.push_back(loadSequence("2001cr.seq"));
- _data->player->sequences.push_back(loadSequence("2001cdl.seq"));
- _data->player->sequences.push_back(loadSequence("2001cdr.seq"));
- _data->player->sequences.push_back(loadSequence("2001cdm.seq"));
- _data->player->sequences.push_back(loadSequence("2001csgr.seq"));
- _data->player->sequences.push_back(loadSequence("2001csgl.seq"));
- _data->player->sequences.push_back(loadSequence("2001dbk.seq"));
-}
-
-void Fight::loadMilosOpponent() {
- REGISTER_OPPONENT_FUNCTIONS(Milos)
-
- _data->opponent->sequences.push_back(loadSequence("2001or.seq"));
- _data->opponent->sequences.push_back(loadSequence("2001oal.seq"));
- _data->opponent->sequences.push_back(loadSequence("2001oam.seq"));
- _data->opponent->sequences.push_back(loadSequence("2001okl.seq"));
- _data->opponent->sequences.push_back(loadSequence("2001okm.seq"));
- _data->opponent->sequences.push_back(loadSequence("2001dbk.seq"));
- _data->opponent->sequences.push_back(loadSequence("2001wbk.seq"));
-
- getSound()->playSound(kEntityTables0, "MUS027", SoundManager::kFlagDefault);
-
- _data->opponent->field_38 = 35;
-}
-
-void Fight::handleActionMilos(Fighter *fighter, FightAction action) {
- switch (action) {
- default:
- handleAction(fighter, action);
- return;
-
- case kFightAction1:
- if (fighter->sequenceIndex != 1 || CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 6, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 3, kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction2:
- if ((fighter->sequenceIndex != 2 && fighter->sequenceIndex != 3) || CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 6, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 4, kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction128:
- if (fighter->sequenceIndex != 1 || CHECK_SEQUENCE2(fighter, 4) || fighter->opponent->sequenceIndex != 1) {
- switch (fighter->opponent->sequenceIndex) {
- default:
- setSequenceAndDraw(fighter, rnd(3) + 1, kFightSequenceType0);
- break;
-
- case 1:
- setSequenceAndDraw(fighter, 1, kFightSequenceType0);
- break;
-
- case 2:
- setSequenceAndDraw(fighter, 3, kFightSequenceType0);
- break;
- }
- } else {
- setSequenceAndDraw(fighter, 4, kFightSequenceType1);
- CALL_FUNCTION0(fighter, update);
- }
- break;
- }
-}
-
-void Fight::updateMilos(Fighter *fighter) {
- if (fighter->frame && CHECK_SEQUENCE2(fighter, 2)) {
-
- // Draw sequences
- if (fighter->opponent->countdown <= 0) {
- setSequenceAndDraw(fighter, 5, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 6, kFightSequenceType1);
-
- getSound()->removeFromQueue(kEntityTables0);
- getSound()->playSound(kEntityTrain, "MUS029", SoundManager::kFlagDefault);
-
- CALL_FUNCTION1(fighter, handleAction, kFightActionWin);
- }
-
- if (fighter->sequenceIndex == 4) {
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction4);
- _endType = kFightEndLost;
- }
- }
-
- update(fighter);
-}
-
-bool Fight::canInteractMilos(Fighter const *fighter, FightAction action) {
- if (!_data)
- error("Fight::canInteractMilos - invalid data!");
-
- if (action != kFightAction128
- || _data->player->sequenceIndex != 1
- || !fighter->frame
- || CHECK_SEQUENCE2(fighter, 4)
- || fighter->opponent->sequenceIndex != 1) {
- return canInteract(fighter);
- }
-
- _engine->getCursor()->setStyle(kCursorHand);
-
- return true;
-}
-
-void Fight::handleOpponentActionMilos(Fighter *fighter, FightAction action) {
- if (action == kFightAction4) {
- setSequenceAndDraw(fighter, 5, kFightSequenceType1);
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- } else {
- if (action != kFightAction131)
- handleAction(fighter, action);
- }
-}
-
-void Fight::updateOpponentMilos(Fighter *fighter) {
- // This is an opponent struct!
- Opponent *opponent = (Opponent *)fighter;
-
- if (!opponent->field_38 && CALL_FUNCTION1(opponent, canInteract, kFightAction1) && !opponent->sequenceIndex2) {
-
- if (opponent->opponent->field_34 >= 2) {
- switch (rnd(5)) {
- default:
- break;
-
- case 0:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- break;
-
- case 1:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- break;
-
- case 2:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType1);
- break;
-
- case 3:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
-
- case 4:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 1, kFightSequenceType2);
- break;
- }
- } else {
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- }
-
- // Update field_38
- if (opponent->opponent->field_34 < 5)
- opponent->field_38 = 6 * (5 - opponent->opponent->field_34);
- else
- opponent->field_38 = 0;
- }
-
- if (opponent->frame && CHECK_SEQUENCE2(opponent, 2)) {
- if (opponent->sequenceIndex == 1 || opponent->sequenceIndex == 2)
- CALL_FUNCTION1(opponent->opponent, handleAction, (FightAction)opponent->sequenceIndex);
-
- if (opponent->opponent->countdown <= 0) {
- getSound()->removeFromQueue(kEntityTables0);
- CALL_FUNCTION1(opponent, handleAction, kFightActionLost);
- }
- }
-
- updateOpponent(opponent);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Anna
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::loadAnnaPlayer() {
- if (!_data)
- error("Fight::loadAnnaPlayer - invalid data!");
-
- // Special case: we are using some shared functions directly
- _data->player->handleAction = new Common::Functor2Mem<Fighter *, FightAction, void, Fight>(this, &Fight::handleActionAnna);
- _data->player->update = new Common::Functor1Mem<Fighter *, void, Fight>(this, &Fight::update);
- _data->player->canInteract = new Common::Functor2Mem<Fighter const *, FightAction, bool, Fight>(this, &Fight::canInteract);
-
- _data->player->sequences.push_back(loadSequence("2002cr.seq"));
- _data->player->sequences.push_back(loadSequence("2002cdl.seq"));
- _data->player->sequences.push_back(loadSequence("2002cdr.seq"));
- _data->player->sequences.push_back(loadSequence("2002cdm.seq"));
- _data->player->sequences.push_back(loadSequence("2002lbk.seq"));
-}
-
-void Fight::loadAnnaOpponent() {
- if (!_data)
- error("Fight::loadAnnaOpponent - invalid data!");
-
- // Special case: we are using some shared functions directly
- _data->opponent->handleAction = new Common::Functor2Mem<Fighter *, FightAction, void, Fight>(this, &Fight::handleAction);
- _data->opponent->update = new Common::Functor1Mem<Fighter *, void, Fight>(this, &Fight::updateOpponentAnna);
- _data->opponent->canInteract = new Common::Functor2Mem<Fighter const *, FightAction, bool, Fight>(this, &Fight::canInteract);
-
- _data->opponent->sequences.push_back(loadSequence("2002or.seq"));
- _data->opponent->sequences.push_back(loadSequence("2002oal.seq"));
- _data->opponent->sequences.push_back(loadSequence("2002oam.seq"));
- _data->opponent->sequences.push_back(loadSequence("2002oar.seq"));
- _data->opponent->sequences.push_back(loadSequence("2002okr.seq"));
- _data->opponent->sequences.push_back(loadSequence("2002okml.seq"));
- _data->opponent->sequences.push_back(loadSequence("2002okm.seq"));
-
- getSound()->playSound(kEntityTables0, "MUS030", SoundManager::kFlagDefault);
-
- _data->opponent->field_38 = 30;
-}
-
-void Fight::handleActionAnna(Fighter *fighter, FightAction action) {
- switch (action) {
- default:
- handleAction(fighter, action);
- return;
-
- case kFightAction1:
- if ((fighter->sequenceIndex != 1 && fighter->sequenceIndex != 3) || CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 4, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 4, kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction2:
- if ((fighter->sequenceIndex != 2 && fighter->sequenceIndex != 3) || CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 4, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 5, kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction3:
- if ((fighter->sequenceIndex != 2 && fighter->sequenceIndex != 1) || CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 4, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 6, kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction128:
- switch (fighter->opponent->sequenceIndex) {
- default:
- setSequenceAndDraw(fighter, 3, kFightSequenceType0);
- break;
-
- case 1:
- setSequenceAndDraw(fighter, 1, kFightSequenceType0);
- break;
-
- case 2:
- setSequenceAndDraw(fighter, 3, kFightSequenceType0);
- break;
-
- case 3:
- setSequenceAndDraw(fighter, 2, kFightSequenceType0);
- break;
- }
- break;
- }
-
- if (fighter->field_34 > 4) {
- getSound()->removeFromQueue(kEntityTables0);
- bailout(kFightEndWin);
- }
-}
-
-void Fight::updateOpponentAnna(Fighter *fighter) {
- // This is an opponent struct!
- Opponent *opponent = (Opponent *)fighter;
-
- if (!opponent->field_38 && CALL_FUNCTION1(opponent, canInteract, kFightAction1) && !opponent->sequenceIndex2) {
-
- if (opponent->opponent->field_34 >= 2) {
- switch (rnd(6)) {
- default:
- break;
-
- case 0:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- break;
-
- case 1:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- break;
-
- case 2:
- setSequenceAndDraw(opponent, 3, kFightSequenceType0);
- break;
-
- case 3:
- setSequenceAndDraw(opponent, 3, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
-
- case 4:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
-
- case 5:
- setSequenceAndDraw(opponent, 3, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
- }
- }
-
- // Update field_38
- opponent->field_38 = (int32)rnd(15);
- }
-
- if (opponent->frame && CHECK_SEQUENCE2(opponent, 2)) {
- if (opponent->sequenceIndex == 1 || opponent->sequenceIndex == 2 || opponent->sequenceIndex == 3)
- CALL_FUNCTION1(opponent->opponent, handleAction, (FightAction)opponent->sequenceIndex);
-
- if (opponent->opponent->countdown <= 0) {
- getSound()->removeFromQueue(kEntityTables0);
- CALL_FUNCTION1(opponent, handleAction, kFightActionLost);
- }
- }
-
- updateOpponent(opponent);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Ivo
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::loadIvoPlayer() {
- REGISTER_PLAYER_FUNCTIONS(Ivo)
-
- _data->player->sequences.push_back(loadSequence("2003cr.seq"));
- _data->player->sequences.push_back(loadSequence("2003car.seq"));
- _data->player->sequences.push_back(loadSequence("2003cal.seq"));
- _data->player->sequences.push_back(loadSequence("2003cdr.seq"));
- _data->player->sequences.push_back(loadSequence("2003cdm.seq"));
- _data->player->sequences.push_back(loadSequence("2003chr.seq"));
- _data->player->sequences.push_back(loadSequence("2003chl.seq"));
- _data->player->sequences.push_back(loadSequence("2003ckr.seq"));
- _data->player->sequences.push_back(loadSequence("2003lbk.seq"));
- _data->player->sequences.push_back(loadSequence("2003fbk.seq"));
-
- _data->player->countdown = 5;
-}
-
-void Fight::loadIvoOpponent() {
- REGISTER_OPPONENT_FUNCTIONS(Ivo)
-
- _data->opponent->sequences.push_back(loadSequence("2003or.seq"));
- _data->opponent->sequences.push_back(loadSequence("2003oal.seq"));
- _data->opponent->sequences.push_back(loadSequence("2003oar.seq"));
- _data->opponent->sequences.push_back(loadSequence("2003odm.seq"));
- _data->opponent->sequences.push_back(loadSequence("2003okl.seq"));
- _data->opponent->sequences.push_back(loadSequence("2003okj.seq"));
- _data->opponent->sequences.push_back(loadSequence("blank.seq"));
- _data->opponent->sequences.push_back(loadSequence("csdr.seq"));
- _data->opponent->sequences.push_back(loadSequence("2003l.seq"));
-
- getSound()->playSound(kEntityTables0, "MUS032", SoundManager::kFlagDefault);
-
- _data->opponent->countdown = 5;
- _data->opponent->field_38 = 15;
-}
-
-void Fight::handleActionIvo(Fighter *fighter, FightAction action) {
- switch (action) {
- default:
- handleAction(fighter, action);
- return;
-
- case kFightAction1:
- if (fighter->sequenceIndex != 1 || CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 7, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 4, kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- }
- break;
-
- case kFightAction2:
- if ((fighter->sequenceIndex != 2 && fighter->sequenceIndex != 3) || CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 7, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 5, kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- }
- break;
-
- case kFightAction128:
- switch (fighter->opponent->sequenceIndex) {
- default:
- case 1:
- setSequenceAndDraw(fighter, 1, kFightSequenceType0);
- break;
-
- case 2:
- setSequenceAndDraw(fighter, 2, kFightSequenceType0);
- break;
- }
- break;
-
- case kFightAction129:
- setSequenceAndDraw(fighter, (fighter->opponent->countdown > 1) ? 4 : 3, fighter->sequenceIndex ? kFightSequenceType2 : kFightSequenceType0);
- break;
-
- case kFightAction130:
- setSequenceAndDraw(fighter, 3, fighter->sequenceIndex ? kFightSequenceType2 : kFightSequenceType0);
- break;
- }
-}
-
-void Fight::updateIvo(Fighter *fighter) {
-
- if ((fighter->sequenceIndex == 3 || fighter->sequenceIndex == 4) && !fighter->frameIndex)
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction131);
-
- if (fighter->frame && CHECK_SEQUENCE2(fighter, 2)) {
-
- // Draw sequences
- if (fighter->opponent->countdown <= 0) {
- setSequenceAndDraw(fighter, 9, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, 8, kFightSequenceType1);
- getSound()->removeFromQueue(kEntityTables0);
-
- CALL_FUNCTION1(fighter, handleAction, kFightActionWin);
- return;
- }
-
- if (fighter->sequenceIndex == 3 || fighter->sequenceIndex == 4)
- CALL_FUNCTION1(fighter->opponent, handleAction, (FightAction)fighter->sequenceIndex);
- }
-
- update(fighter);
-}
-
-bool Fight::canInteractIvo(Fighter const *fighter, FightAction action) {
- if (action == kFightAction129 || action == kFightAction130)
- return (fighter->sequenceIndex >= 8);
-
- return canInteract(fighter);
-}
-
-void Fight::handleOpponentActionIvo(Fighter *fighter, FightAction action) {
- // This is an opponent struct!
- Opponent *opponent = (Opponent *)fighter;
-
- switch (action) {
- default:
- handleAction(fighter, action);
- break;
-
- case kFightAction3:
- if ((opponent->sequenceIndex != 1 && opponent->sequenceIndex != 3) || CHECK_SEQUENCE2(opponent, 4)) {
- setSequenceAndDraw(opponent, 6, kFightSequenceType1);
- setSequenceAndDraw(opponent->opponent, 6, kFightSequenceType1);
- CALL_FUNCTION1(opponent->opponent, handleAction, kFightAction103);
- }
- break;
-
- case kFightAction4:
- if ((opponent->sequenceIndex != 2 && opponent->sequenceIndex != 3) || CHECK_SEQUENCE2(opponent, 4)) {
- setSequenceAndDraw(opponent, 6, kFightSequenceType1);
- setSequenceAndDraw(opponent->opponent, 5, kFightSequenceType1);
- CALL_FUNCTION1(opponent->opponent, handleAction, kFightAction103);
- }
- break;
-
- case kFightAction131:
- if (opponent->sequenceIndex)
- break;
-
- if (rnd(100) <= (unsigned int)(opponent->countdown > 2 ? 60 : 75)) {
- setSequenceAndDraw(opponent, 3 , kFightSequenceType1);
- if (opponent->opponent->sequenceIndex == 4)
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- }
- break;
- }
-}
-
-void Fight::updateOpponentIvo(Fighter *fighter) {
- // This is an opponent struct!
- Opponent *opponent = (Opponent *)fighter;
-
- if (!opponent->field_38 && CALL_FUNCTION1(opponent, canInteract, kFightAction1) && !opponent->sequenceIndex2) {
-
- if (opponent->opponent->field_34 >= 2) {
- switch (rnd(5)) {
- default:
- break;
-
- case 0:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- break;
-
- case 1:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- break;
-
- case 2:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
-
- case 3:
- setSequenceAndDraw(opponent, 0, kFightSequenceType2);
- setSequenceAndDraw(opponent, 1, kFightSequenceType2);
- break;
-
- case 4:
- setSequenceAndDraw(opponent, 0, kFightSequenceType1);
- setSequenceAndDraw(opponent, 1, kFightSequenceType2);
- break;
- }
- }
-
- // Update field_38
- opponent->field_38 = 3 * opponent->countdown + (int32)rnd(10);
- }
-
- if (opponent->frame && CHECK_SEQUENCE2(opponent, 2)) {
-
- if (opponent->opponent->countdown <= 0) {
- setSequenceAndDraw(opponent, 7, kFightSequenceType1);
- setSequenceAndDraw(opponent->opponent, 8, kFightSequenceType1);
- getSound()->removeFromQueue(kEntityTables0);
-
- CALL_FUNCTION1(opponent->opponent, handleAction, kFightActionWin);
-
- return;
- }
-
- if (opponent->sequenceIndex == 1 || opponent->sequenceIndex == 2)
- CALL_FUNCTION1(opponent->opponent, handleAction, (FightAction)opponent->sequenceIndex);
- }
-
- updateOpponent(opponent);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Salko
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::loadSalkoPlayer() {
- REGISTER_PLAYER_FUNCTIONS(Salko)
-
- _data->player->sequences.push_back(loadSequence("2004cr.seq"));
- _data->player->sequences.push_back(loadSequence("2004cdr.seq"));
- _data->player->sequences.push_back(loadSequence("2004chj.seq"));
- _data->player->sequences.push_back(loadSequence("2004bk.seq"));
-
- _data->player->countdown = 2;
-}
-
-void Fight::loadSalkoOpponent() {
- REGISTER_OPPONENT_FUNCTIONS(Salko)
-
- _data->opponent->sequences.push_back(loadSequence("2004or.seq"));
- _data->opponent->sequences.push_back(loadSequence("2004oam.seq"));
- _data->opponent->sequences.push_back(loadSequence("2004oar.seq"));
- _data->opponent->sequences.push_back(loadSequence("2004okr.seq"));
- _data->opponent->sequences.push_back(loadSequence("2004ohm.seq"));
- _data->opponent->sequences.push_back(loadSequence("blank.seq"));
-
- getSound()->playSound(kEntityTables0, "MUS035", SoundManager::kFlagDefault);
-
- _data->opponent->countdown = 3;
- _data->opponent->field_38 = 30;
-}
-
-void Fight::handleActionSalko(Fighter *fighter, FightAction action) {
- switch (action) {
- default:
- handleAction(fighter, action);
- return;
-
- case kFightAction1:
- case kFightAction2:
- if (fighter->sequenceIndex != 1 && CHECK_SEQUENCE2(fighter, 4)) {
- fighter->field_34 = 0;
-
- setSequenceAndDraw(fighter, 3, kFightSequenceType1);
- setSequenceAndDraw(fighter->opponent, (action == kFightAction1 ? 3 : 4), kFightSequenceType1);
-
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
-
- if (action == kFightAction2)
- fighter->countdown= 0;
-
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction5:
- if (fighter->sequenceIndex != 3) {
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- }
- break;
-
- case kFightAction128:
- setSequenceAndDraw(fighter, 1, kFightSequenceType0);
- fighter->field_34 = 0;
- break;
-
- case kFightAction131:
- setSequenceAndDraw(fighter, 2, (fighter->sequenceIndex ? kFightSequenceType2 : kFightSequenceType0));
- break;
- }
-}
-
-void Fight::updateSalko(Fighter *fighter) {
- update(fighter);
-
- // The original doesn't check for currentSequence2 != NULL (might not happen when everything is working properly, but crashes with our current implementation)
- if (fighter->frame && CHECK_SEQUENCE2(fighter, 2)) {
-
- if (fighter->opponent->countdown <= 0) {
- getSound()->removeFromQueue(kEntityTables0);
- bailout(kFightEndWin);
-
- return;
- }
-
- if (fighter->sequenceIndex == 2)
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction2);
- }
-}
-
-bool Fight::canInteractSalko(Fighter const *fighter, FightAction action) {
- if (action == kFightAction131) {
- if (fighter->sequenceIndex == 1) {
- if (fighter->opponent->countdown <= 0)
- _engine->getCursor()->setStyle(kCursorHand);
-
- return true;
- }
-
- return false;
- }
-
- return canInteract(fighter);
-}
-
-void Fight::handleOpponentActionSalko(Fighter *fighter, FightAction action) {
- if (action == kFightAction2) {
- setSequenceAndDraw(fighter, 5, kFightSequenceType1);
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- } else {
- handleAction(fighter, action);
- }
-}
-
-void Fight::updateOpponentSalko(Fighter *fighter) {
- // This is an opponent struct
- Opponent *opponent = (Opponent *)fighter;
-
- if (!opponent->field_38 && CALL_FUNCTION1(opponent, canInteract, kFightAction1) && !opponent->sequenceIndex2) {
-
- switch (rnd(5)) {
- default:
- break;
-
- case 0:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- break;
-
- case 1:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- break;
-
- case 2:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
-
- case 3:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- setSequenceAndDraw(opponent, 1, kFightSequenceType2);
- break;
-
- case 4:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 1, kFightSequenceType2);
- break;
- }
-
- // Update field_38
- opponent->field_38 = 4 * opponent->countdown;
- }
-
- if (opponent->frame && CHECK_SEQUENCE2(opponent, 2)) {
- if (opponent->opponent->countdown <= 0) {
- getSound()->removeFromQueue(kEntityTables0);
- bailout(kFightEndLost);
-
- // Stop processing
- return;
- }
-
- if (opponent->sequenceIndex == 1 || opponent->sequenceIndex == 2)
- CALL_FUNCTION1(opponent->opponent, handleAction, (FightAction)opponent->sequenceIndex);
- }
-
- updateOpponent(opponent);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Vesna
-//////////////////////////////////////////////////////////////////////////
-
-void Fight::loadVesnaPlayer() {
- REGISTER_PLAYER_FUNCTIONS(Vesna)
-
- _data->player->sequences.push_back(loadSequence("2005cr.seq"));
- _data->player->sequences.push_back(loadSequence("2005cdr.seq"));
- _data->player->sequences.push_back(loadSequence("2005cbr.seq"));
- _data->player->sequences.push_back(loadSequence("2005bk.seq"));
- _data->player->sequences.push_back(loadSequence("2005cdm1.seq"));
- _data->player->sequences.push_back(loadSequence("2005chl.seq"));
-}
-
-void Fight::loadVesnaOpponent() {
- REGISTER_OPPONENT_FUNCTIONS(Vesna)
-
- _data->opponent->sequences.push_back(loadSequence("2005or.seq"));
- _data->opponent->sequences.push_back(loadSequence("2005oam.seq"));
- _data->opponent->sequences.push_back(loadSequence("2005oar.seq"));
- _data->opponent->sequences.push_back(loadSequence("2005okml.seq"));
- _data->opponent->sequences.push_back(loadSequence("2005okr.seq"));
- _data->opponent->sequences.push_back(loadSequence("2005odm1.seq"));
- _data->opponent->sequences.push_back(loadSequence("2005csbm.seq"));
- _data->opponent->sequences.push_back(loadSequence("2005oam4.seq"));
-
- getSound()->playSound(kEntityTables0, "MUS038", SoundManager::kFlagDefault);
-
- _data->opponent->countdown = 4;
- _data->opponent->field_38 = 30;
-}
-
-void Fight::handleActionVesna(Fighter *fighter, FightAction action) {
- switch (action) {
- default:
- handleAction(fighter, action);
- return;
-
- case kFightAction1:
- if (fighter->sequenceIndex != 1) {
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction2:
- if (fighter->sequenceIndex != 2) {
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- } else {
- fighter->field_34++;
- }
- break;
-
- case kFightAction5:
- if (fighter->sequenceIndex != 3) {
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- CALL_FUNCTION0(fighter, update);
- }
- break;
-
- case kFightAction128:
- if (fighter->sequenceIndex == 1 && fighter->opponent->sequenceIndex == 1 && CHECK_SEQUENCE2(fighter, 4)) {
- setSequenceAndDraw(fighter, 5, kFightSequenceType1);
- } else {
- setSequenceAndDraw(fighter, (fighter->opponent->sequenceIndex == 5) ? 3 : 1, kFightSequenceType0);
- }
- break;
-
- case kFightAction132:
- setSequenceAndDraw(fighter, 2, kFightSequenceType0);
- break;
- }
-
- if (fighter->field_34 > 10) {
- setSequenceAndDraw(fighter->opponent, 5, kFightSequenceType2);
- fighter->opponent->countdown = 1;
- fighter->field_34 = 0;
- }
-}
-
-void Fight::updateVesna(Fighter *fighter) {
- if (fighter->frame && CHECK_SEQUENCE2(fighter, 2)) {
-
- if (fighter->sequenceIndex == 3)
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction3);
-
- if (fighter->opponent->countdown <= 0) {
- getSound()->removeFromQueue(kEntityTables0);
- bailout(kFightEndWin);
- return;
- }
-
- if (fighter->sequenceIndex == 5)
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction5);
- }
-
- update(fighter);
-}
-
-bool Fight::canInteractVesna(Fighter const *fighter, FightAction action) {
- if (action != kFightAction128)
- return canInteract(fighter);
-
- if (fighter->sequenceIndex != 1) {
-
- if (fighter->opponent->sequenceIndex == 5) {
- _engine->getCursor()->setStyle(kCursorDown);
- return true;
- }
-
- return canInteract(fighter);
- }
-
- if (fighter->opponent->sequenceIndex == 1 && CHECK_SEQUENCE2(fighter, 4)) {
- _engine->getCursor()->setStyle(kCursorPunchLeft);
- return true;
- }
-
- return false;
-}
-
-void Fight::handleOpponentActionVesna(Fighter *fighter, FightAction action) {
- switch (action) {
- default:
- handleAction(fighter, action);
- break;
-
- case kFightAction3:
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- break;
-
- case kFightAction5:
- setSequenceAndDraw(fighter, 7, kFightSequenceType1);
- CALL_FUNCTION1(fighter->opponent, handleAction, kFightAction103);
- if (fighter->countdown <= 1)
- fighter->countdown = 1;
- break;
-
- case kFightAction131:
- break;
- }
-}
-
-void Fight::updateOpponentVesna(Fighter *fighter) {
- // This is an opponent struct
- Opponent *opponent = (Opponent *)fighter;
-
- if (!opponent->field_38 && CALL_FUNCTION1(opponent, canInteract, kFightAction1) && !opponent->sequenceIndex2) {
-
- if (opponent->opponent->field_34 == 1) {
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- } else {
- switch (rnd(6)) {
- default:
- break;
-
- case 0:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- break;
-
- case 1:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 1, kFightSequenceType2);
- break;
-
- case 2:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- break;
-
- case 3:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
-
- case 4:
- setSequenceAndDraw(opponent, 1, kFightSequenceType0);
- setSequenceAndDraw(opponent, 2, kFightSequenceType2);
- break;
-
- case 5:
- setSequenceAndDraw(opponent, 2, kFightSequenceType0);
- setSequenceAndDraw(opponent, 1, kFightSequenceType2);
- break;
- }
- }
-
- // Update field_38
- opponent->field_38 = 4 * opponent->countdown;
- }
-
- if (opponent->frame && CHECK_SEQUENCE2(opponent, 2)) {
- if (opponent->sequenceIndex == 1 || opponent->sequenceIndex == 2 || opponent->sequenceIndex == 5)
- CALL_FUNCTION1(opponent->opponent, handleAction, (FightAction)opponent->sequenceIndex);
-
- if (opponent->opponent->countdown <= 0) {
-
- switch (opponent->sequenceIndex) {
- default:
- break;
-
- case 1:
- setSequenceAndDraw(opponent, 3, kFightSequenceType1);
- break;
-
- case 2:
- setSequenceAndDraw(opponent, 4, kFightSequenceType1);
- break;
-
- case 5:
- setSequenceAndDraw(opponent, 6, kFightSequenceType1);
- break;
- }
-
- setSequenceAndDraw(opponent->opponent, 4, kFightSequenceType1);
-
- CALL_FUNCTION1(opponent, handleAction, kFightActionLost);
- CALL_FUNCTION0(opponent->opponent, update);
- CALL_FUNCTION0(opponent, update);
-
- getSound()->removeFromQueue(kEntityTables0);
-
- // Stop processing
- return;
- }
- }
-
- updateOpponent(opponent);
-}
-
-} // End of namespace LastExpress
diff --git a/engines/lastexpress/game/fight.h b/engines/lastexpress/game/fight.h
deleted file mode 100644
index a33cc93a29..0000000000
--- a/engines/lastexpress/game/fight.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef LASTEXPRESS_FIGHT_H
-#define LASTEXPRESS_FIGHT_H
-
-/*
- Fight structure
- ---------------
- uint32 {4} - player struct
- uint32 {4} - opponent struct
- uint32 {4} - hasLost flag
-
- byte {1} - isRunning
-
- Fight participant structure
- ---------------------------
- uint32 {4} - function pointer
- uint32 {4} - pointer to fight structure
- uint32 {4} - pointer to opponent (fight participant structure)
- uint32 {4} - array of sequences
- uint32 {4} - number of sequences
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint16 {2} - ??
- uint16 {2} - ?? - only for opponent structure
- uint32 {4} - ?? - only for opponent structure
-
-*/
-
-#include "lastexpress/shared.h"
-
-#include "lastexpress/eventhandler.h"
-
-#include "common/array.h"
-
-namespace LastExpress {
-
-class LastExpressEngine;
-class Sequence;
-class SequenceFrame;
-
-//////////////////////////////////////////////////////////////////////////
-// TODO : objectify!
-class Fight : public EventHandler {
-public:
- enum FightEndType {
- kFightEndWin = 0,
- kFightEndLost = 1,
- kFightEndExit = 2
- };
-
- Fight(LastExpressEngine *engine);
- ~Fight();
-
- FightEndType setup(FightType type);
-
- void eventMouse(const Common::Event &ev);
- void eventTick(const Common::Event &ev);
-
- void setStopped();
- void resetState() { _state = 0; }
-
-private:
- enum FightSequenceType {
- kFightSequenceType0 = 0,
- kFightSequenceType1 = 1,
- kFightSequenceType2 = 2
- };
-
- enum FightAction {
- kFightAction1 = 1,
- kFightAction2 = 2,
- kFightAction3 = 3,
- kFightAction4 = 4,
- kFightAction5 = 5,
- kFightAction101 = 101,
- kFightActionResetFrame = 102,
- kFightAction103 = 103,
- kFightActionWin = 104,
- kFightActionLost = 105,
- kFightAction128 = 128,
- kFightAction129 = 129,
- kFightAction130 = 130,
- kFightAction131 = 131,
- kFightAction132 = 132
- };
-
- struct Fighter {
- Common::Functor2<Fighter *, FightAction, void> *handleAction;
- Common::Functor1<Fighter *, void> *update;
- Common::Functor2<Fighter const *, FightAction, bool> *canInteract;
- Fighter *opponent;
- Common::Array<Sequence *> sequences;
- uint32 sequenceIndex;
- Sequence *sequence;
- SequenceFrame *frame;
- uint32 frameIndex;
- uint32 field_24;
- FightAction action;
- uint32 sequenceIndex2;
- int32 countdown; // countdown before loosing ?
- uint32 field_34;
-
- Fighter() {
- handleAction = NULL;
- update = NULL;
- canInteract = NULL;
-
- opponent = NULL;
-
- sequenceIndex = 0;
- sequence = NULL;
- frame = NULL;
- frameIndex = 0;
-
- field_24 = 0;
-
- action = kFightAction101;
- sequenceIndex2 = 0;
-
- countdown = 1;
-
- field_34 = 0;
- }
- };
-
- // Opponent struct
- struct Opponent : Fighter {
- int32 field_38;
-
- Opponent() : Fighter() {
- field_38 = 0;
- }
- };
-
- struct FightData {
- Fighter *player;
- Opponent *opponent;
- int32 index;
-
- Sequence *sequences[20];
- Common::String names[20];
-
- bool isRunning;
-
- FightData() {
- player = new Fighter();
- opponent = new Opponent();
-
- // Set opponents
- player->opponent = opponent;
- opponent->opponent = player;
-
- index = 0;
-
- isRunning = false;
- }
- };
-
- LastExpressEngine *_engine;
- FightData *_data;
- FightEndType _endType;
- int _state;
-
- bool _handleTimer;
-
- // Events
- void handleTick(const Common::Event &ev, bool unknown);
-
- // State
- void bailout(FightEndType type);
-
-
- // Drawing
- void setSequenceAndDraw(Fighter *fighter, uint32 sequenceIndex, FightSequenceType type) const;
- void draw(Fighter *fighter) const;
-
- // Cleanup
- void clearData();
- void clearSequences(Fighter *fighter) const;
-
- //////////////////////////////////////////////////////////////////////////
- // Loading
- void loadData(FightType type);
-
- // Shared
- void processFighter(Fighter *fighter);
-
- // Default functions
- void handleAction(Fighter *fighter, FightAction action);
- void update(Fighter *fighter);
- bool canInteract(Fighter const *fighter, FightAction = (FightAction)0);
- void updateOpponent(Fighter *fighter);
-
- // Milos
- void loadMilosPlayer();
- void loadMilosOpponent();
- void handleActionMilos(Fighter *fighter, FightAction action);
- void updateMilos(Fighter *fighter);
- bool canInteractMilos(Fighter const *fighter, FightAction action);
- void handleOpponentActionMilos(Fighter *fighter, FightAction action);
- void updateOpponentMilos(Fighter *fighter);
-
- // Anna
- void loadAnnaPlayer();
- void loadAnnaOpponent();
- void handleActionAnna(Fighter *fighter, FightAction action);
- void updateOpponentAnna(Fighter *fighter);
-
- // Ivo
- void loadIvoPlayer();
- void loadIvoOpponent();
- void handleActionIvo(Fighter *fighter, FightAction action);
- void updateIvo(Fighter *fighter);
- bool canInteractIvo(Fighter const *fighter, FightAction action);
- void handleOpponentActionIvo(Fighter *fighter, FightAction action);
- void updateOpponentIvo(Fighter *fighter);
-
- // Salko
- void loadSalkoPlayer();
- void loadSalkoOpponent();
- void handleActionSalko(Fighter *fighter, FightAction action);
- void updateSalko(Fighter *fighter);
- bool canInteractSalko(Fighter const *fighter, FightAction action);
- void handleOpponentActionSalko(Fighter *fighter, FightAction action);
- void updateOpponentSalko(Fighter *fighter);
-
- // Vesna
- void loadVesnaPlayer();
- void loadVesnaOpponent();
- void handleActionVesna(Fighter *fighter, FightAction action);
- void updateVesna(Fighter *fighter);
- bool canInteractVesna(Fighter const *fighter, FightAction action);
- void handleOpponentActionVesna(Fighter *fighter, FightAction action);
- void updateOpponentVesna(Fighter *fighter);
-};
-
-} // End of namespace LastExpress
-
-#endif // LASTEXPRESS_FIGHT_H
diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp
index adf6ff772e..e417b1ec0d 100644
--- a/engines/lastexpress/game/inventory.cpp
+++ b/engines/lastexpress/game/inventory.cpp
@@ -27,11 +27,14 @@
#include "lastexpress/data/snd.h"
#include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/menu/menu.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/graphics.h"
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -155,14 +158,14 @@ void Inventory::handleMouseEvent(const Common::Event &ev) {
_portraitHighlighted = false;
_isOpened = false;
- getSound()->playSoundWithSubtitles("LIB039.SND", SoundManager::kFlagMenuClock, kEntityPlayer);
+ getSound()->playSoundWithSubtitles("LIB039.SND", kFlagMenuClock, kEntityPlayer);
getMenu()->show(true, kSavegameTypeIndex, 0);
} else if (ev.type == Common::EVENT_RBUTTONDOWN) {
if (getGlobalTimer()) {
- if (getSound()->isBuffered("TIMER"))
- getSound()->removeFromQueue("TIMER");
+ if (getSoundQueue()->isBuffered("TIMER"))
+ getSoundQueue()->removeFromQueue("TIMER");
setGlobalTimer(900);
}
@@ -436,7 +439,7 @@ void Inventory::showHourGlass(){
//////////////////////////////////////////////////////////////////////////
Inventory::InventoryEntry *Inventory::get(InventoryItem item) {
if (item >= kPortraitOriginal)
- error("Inventory::getEntry: Invalid inventory item!");
+ error("[Inventory::get] Invalid inventory item");
return &_entries[item];
}
@@ -620,7 +623,7 @@ void Inventory::drawEgg() {
// Blinking egg: we need to blink the egg for delta time, with the blinking getting faster until it's always lit.
void Inventory::drawBlinkingEgg() {
- warning("Inventory::drawEgg - blinking not implemented!");
+ warning("[Inventory::drawBlinkingEgg] Blinking not implemented");
//// TODO show egg (with or without mouseover)
@@ -629,7 +632,7 @@ void Inventory::drawBlinkingEgg() {
// if (getGlobalTimer() + ticks >= 90)
// getSound()->playSoundWithSubtitles("TIMER.SND", 50331664, kEntityPlayer);
- // if (getSound()->isBuffered("TIMER"))
+ // if (getSoundQueue()->isBuffered("TIMER"))
// setGlobalTimer(0);
//}
diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp
index 0911c60de0..aeac8cff98 100644
--- a/engines/lastexpress/game/logic.cpp
+++ b/engines/lastexpress/game/logic.cpp
@@ -30,20 +30,25 @@
// Entities
#include "lastexpress/entities/chapters.h"
+// Fight
+#include "lastexpress/fight/fight.h"
+
// Game
#include "lastexpress/game/action.h"
#include "lastexpress/game/beetle.h"
#include "lastexpress/game/entities.h"
-#include "lastexpress/game/fight.h"
#include "lastexpress/game/inventory.h"
-#include "lastexpress/game/menu.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savegame.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/menu/menu.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/graphics.h"
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -149,7 +154,7 @@ void Logic::eventMouse(const Common::Event &ev) {
_engine->getCursor()->setStyle(getInventory()->get(kItemWhistle)->cursor);
// Check if clicked
- if (ev.type == Common::EVENT_LBUTTONUP && !getSound()->isBuffered("LIB045")) {
+ if (ev.type == Common::EVENT_LBUTTONUP && !getSoundQueue()->isBuffered("LIB045")) {
getSound()->playSoundEvent(kEntityPlayer, 45);
@@ -408,7 +413,7 @@ void Logic::eventTick(const Common::Event &) {
void Logic::resetState() {
getState()->scene = kSceneDefault;
- warning("Logic::resetState: not implemented! You need to restart the engine until this is implemented.");
+ warning("[Logic::resetState] Not implemented! You need to restart the engine until this is implemented.");
}
/**
@@ -421,7 +426,7 @@ void Logic::resetState() {
*/
void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, bool showScene) const {
- getSound()->processEntries();
+ getSoundQueue()->processEntries();
getEntities()->reset();
getFlags()->isGameRunning = false;
getSavePoints()->reset();
@@ -429,16 +434,16 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo
if (showScene) {
- getSound()->processEntry(SoundManager::kSoundType11);
+ getSoundQueue()->processEntry(kSoundType11);
if (sceneIndex && !getFlags()->mouseRightClick) {
getScenes()->loadScene(sceneIndex);
- while (getSound()->isBuffered(kEntityTables4)) {
+ while (getSoundQueue()->isBuffered(kEntityTables4)) {
if (getFlags()->mouseRightClick)
break;
- getSound()->updateQueue();
+ getSoundQueue()->updateQueue();
}
}
}
@@ -448,7 +453,7 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo
}
void Logic::switchChapter() const {
- getSound()->clearStatus();
+ getSoundQueue()->clearStatus();
switch(getState()->progress.chapter) {
default:
@@ -488,7 +493,7 @@ void Logic::switchChapter() const {
}
void Logic::playFinalSequence() const {
- getSound()->processEntries();
+ getSoundQueue()->processEntries();
_action->playAnimation(kEventFinalSequence);
showCredits();
@@ -501,7 +506,7 @@ void Logic::playFinalSequence() const {
}
void Logic::showCredits() const {
- error("Logic::showCredits: not implemented!");
+ error("[Logic::showCredits] Not implemented");
}
//////////////////////////////////////////////////////////////////////////
diff --git a/engines/lastexpress/game/object.cpp b/engines/lastexpress/game/object.cpp
index a600075953..d9e9e4279a 100644
--- a/engines/lastexpress/game/object.cpp
+++ b/engines/lastexpress/game/object.cpp
@@ -39,7 +39,7 @@ Objects::Objects(LastExpressEngine *engine) : _engine(engine) {}
const Objects::Object Objects::get(ObjectIndex index) const {
if (index >= kObjectMax)
- error("Objects::get - internal error: invalid object index (%d)", index);
+ error("[Objects::get] Invalid object index (%d)", index);
return _objects[index];
}
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index 5d06ecab13..ebada5dd4e 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -24,11 +24,14 @@
#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/menu/menu.h"
+
+#include "lastexpress/sound/queue.h"
+
#include "lastexpress/debug.h"
#include "lastexpress/lastexpress.h"
#include "lastexpress/helpers.h"
@@ -72,10 +75,10 @@ void SaveLoad::initStream() {
void SaveLoad::flushStream(GameId id) {
Common::OutSaveFile *save = openForSaving(id);
if (!save)
- error("SaveLoad::flushStream: cannot open savegame (%s)!", getFilename(id).c_str());
+ error("[SaveLoad::flushStream] Cannot open savegame (%s)", getFilename(id).c_str());
if (!_savegame)
- error("SaveLoad::flushStream: savegame stream is invalid");
+ error("[SaveLoad::flushStream] Savegame stream is invalid");
save->write(_savegame->getData(), (uint32)_savegame->size());
@@ -106,7 +109,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
SavegameMainHeader mainHeader;
mainHeader.saveLoadWithSerializer(ser);
if (!mainHeader.isValid())
- error("SaveLoad::init - Savegame seems to be corrupted (invalid header)");
+ error("[SaveLoad::init] Savegame seems to be corrupted (invalid header)");
// Reset cached entry headers if needed
if (resetHeaders) {
@@ -124,7 +127,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
while (_savegame->pos() < _savegame->size() && !_savegame->eos() && !_savegame->err()) {
// Update sound queue while we go through the savegame
- getSound()->updateQueue();
+ getSoundQueue()->updateQueue();
SavegameEntryHeader *entry = new SavegameEntryHeader();
entry->saveLoadWithSerializer(ser);
@@ -145,10 +148,10 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
void SaveLoad::loadStream(GameId id) {
Common::InSaveFile *save = openForLoading(id);
if (save->size() < 32)
- error("SaveLoad::init - Savegame seems to be corrupted (not enough data: %i bytes)", save->size());
+ error("[SaveLoad::loadStream] Savegame seems to be corrupted (not enough data: %i bytes)", save->size());
if (!_savegame)
- error("SaveLoad::loadStream: savegame stream is invalid");
+ error("[SaveLoad::loadStream] Savegame stream is invalid");
// Load all savegame data
uint8* buf = new uint8[8192];
@@ -189,7 +192,7 @@ void SaveLoad::clear(bool clearStream) {
// Load game
void SaveLoad::loadGame(GameId id) {
if (!_savegame)
- error("SaveLoad::loadGame: No savegame stream present!");
+ error("[SaveLoad::loadGame] No savegame stream present");
// Rewind current savegame
_savegame->seek(0);
@@ -197,12 +200,12 @@ void SaveLoad::loadGame(GameId id) {
// Validate main header
SavegameMainHeader header;
if (!loadMainHeader(_savegame, &header)) {
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::saveGame - Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
+ debugC(2, kLastExpressDebugSavegame, "Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
return;
}
if (!_savegame)
- error("SaveLoad::loadGame: No savegame stream present!");
+ error("[SaveLoad::loadGame] No savegame stream present");
// Load the last entry
_savegame->seek(header.offsetEntry);
@@ -216,7 +219,7 @@ void SaveLoad::loadGame(GameId id) {
_gameTicksLastSavegame = getState()->timeTicks;
if (header.keepIndex) {
- getSound()->clearQueue();
+ getSoundQueue()->clearQueue();
readEntry(&type, &entity, &val, false);
}
@@ -227,7 +230,7 @@ void SaveLoad::loadGame(GameId id) {
// Load a specific game entry
void SaveLoad::loadGame(GameId id, uint32 index) {
- error("SaveLoad::loadGame: not implemented! (only loading the last entry is working for now)");
+ error("[SaveLoad::loadGame] Not implemented! (only loading the last entry is working for now)");
}
// Save game
@@ -238,12 +241,12 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
// Validate main header
SavegameMainHeader header;
if (!loadMainHeader(_savegame, &header)) {
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::saveGame - Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
+ debugC(2, kLastExpressDebugSavegame, "Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
return;
}
if (!_savegame)
- error("SaveLoad::saveGame: savegame stream is invalid");
+ error("[SaveLoad::saveGame] Savegame stream is invalid");
// Validate the current entry if it exists
if (header.count > 0) {
@@ -255,7 +258,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
entry.saveLoadWithSerializer(ser);
if (!entry.isValid()) {
- warning("SaveLoad::saveGame: Invalid entry. This savegame might be corrupted!");
+ warning("[SaveLoad::saveGame] Invalid entry. This savegame might be corrupted");
_savegame->seek(header.offset);
} else if (getState()->time < entry.time || (type == kSavegameTypeTickInterval && getState()->time == entry.time)) {
// Not ready to save a game, skipping!
@@ -293,7 +296,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
// Validate the main header
if (!header.isValid())
- error("SaveLoad::saveGame: main game header is invalid!");
+ error("[SaveLoad::saveGame] Main game header is invalid");
// Write the main header
_savegame->seek(0);
@@ -304,7 +307,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
}
void SaveLoad::saveVolumeBrightness() {
- warning("SaveLoad::saveVolumeBrightness: not implemented!");
+ warning("[SaveLoad::saveVolumeBrightness] Not implemented");
}
//////////////////////////////////////////////////////////////////////////
@@ -316,7 +319,7 @@ bool SaveLoad::loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *he
// Check there is enough data (32 bytes)
if (stream->size() < 32) {
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::loadMainHeader - Savegame seems to be corrupted (not enough data: %i bytes)!", stream->size());
+ debugC(2, kLastExpressDebugSavegame, "Savegame seems to be corrupted (not enough data: %i bytes)", stream->size());
return false;
}
@@ -328,7 +331,7 @@ bool SaveLoad::loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *he
// Validate the header
if (!header->isValid()) {
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::loadMainHeader - Cannot validate main header!");
+ debugC(2, kLastExpressDebugSavegame, "Cannot validate main header");
return false;
}
@@ -345,11 +348,11 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
uint32 _count = (uint32)_savegame->pos() - _prevPosition; \
debugC(kLastExpressDebugSavegame, "Savegame: Writing " #name ": %d bytes", _count); \
if (_count != val)\
- error("SaveLoad::writeEntry: Number of bytes written (%d) differ from expected count (%d)", _count, val); \
+ error("[SaveLoad::writeEntry] Number of bytes written (%d) differ from expected count (%d)", _count, val); \
}
if (!_savegame)
- error("SaveLoad::writeEntry: savegame stream is invalid");
+ error("[SaveLoad::writeEntry] Savegame stream is invalid");
SavegameEntryHeader header;
@@ -376,7 +379,7 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
WRITE_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32);
WRITE_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128);
WRITE_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40);
- WRITE_ENTRY("sound", getSound()->saveLoadWithSerializer(ser), 3 * 4 + getSound()->count() * 64);
+ WRITE_ENTRY("sound", getSoundQueue()->saveLoadWithSerializer(ser), 3 * 4 + getSoundQueue()->count() * 64);
WRITE_ENTRY("savepoints", getSavePoints()->saveLoadWithSerializer(ser), 128 * 16 + 4 + getSavePoints()->count() * 16);
header.offset = (uint32)_savegame->pos() - (originalPosition + 32);
@@ -392,7 +395,7 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
// Validate entry header
if (!header.isValid())
- error("SaveLoad::writeEntry: entry header is invalid");
+ error("[SaveLoad::writeEntry] Entry header is invalid");
// Save the header with the updated info
_savegame->seek(originalPosition);
@@ -409,7 +412,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
uint32 _count = (uint32)_savegame->pos() - _prevPosition; \
debugC(kLastExpressDebugSavegame, "Savegame: Reading " #name ": %d bytes", _count); \
if (_count != val) \
- error("SaveLoad::readEntry: Number of bytes read (%d) differ from expected count (%d)", _count, val); \
+ error("[SaveLoad::readEntry] Number of bytes read (%d) differ from expected count (%d)", _count, val); \
}
#define LOAD_ENTRY_ONLY(name, func) { \
@@ -420,10 +423,10 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
}
if (!type || !entity || !val)
- error("SaveLoad::readEntry: Invalid parameters passed!");
+ error("[SaveLoad::readEntry] Invalid parameters passed");
if (!_savegame)
- error("SaveLoad::readEntry: No savegame stream present!");
+ error("[SaveLoad::readEntry] No savegame stream present");
// Load entry header
SavegameEntryHeader entry;
@@ -431,7 +434,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
entry.saveLoadWithSerializer(ser);
if (!entry.isValid())
- error("SaveLoad::readEntry: entry header is invalid!");
+ error("[SaveLoad::readEntry] Entry header is invalid");
// Init type, entity & value
*type = entry.type;
@@ -451,7 +454,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
LOAD_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32);
LOAD_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128);
LOAD_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40);
- LOAD_ENTRY_ONLY("sound", getSound()->saveLoadWithSerializer(ser));
+ LOAD_ENTRY_ONLY("sound", getSoundQueue()->saveLoadWithSerializer(ser));
LOAD_ENTRY_ONLY("savepoints", getSavePoints()->saveLoadWithSerializer(ser));
// Update chapter
@@ -466,7 +469,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
SaveLoad::SavegameEntryHeader *SaveLoad::getEntry(uint32 index) {
if (index >= _gameHeaders.size())
- error("SaveLoad::getEntry: invalid index (was:%d, max:%d)", index, _gameHeaders.size() - 1);
+ error("[SaveLoad::getEntry] Invalid index (was:%d, max:%d)", index, _gameHeaders.size() - 1);
return _gameHeaders[index];
}
@@ -486,7 +489,7 @@ bool SaveLoad::isSavegamePresent(GameId id) {
// Check if the game has been started in the specific savegame
bool SaveLoad::isSavegameValid(GameId id) {
if (!isSavegamePresent(id)) {
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::isSavegameValid - Savegame does not exist: %s", getFilename(id).c_str());
+ debugC(2, kLastExpressDebugSavegame, "Savegame does not exist: %s", getFilename(id).c_str());
return false;
}
@@ -549,7 +552,7 @@ bool SaveLoad::isGameFinished(uint32 menuIndex, uint32 savegameIndex) {
// Get the file name from the savegame ID
Common::String SaveLoad::getFilename(GameId id) {
if (id >= 6)
- error("SaveLoad::getName - attempting to use an invalid game id. Valid values: 0 - 5, was %d", id);
+ error("[SaveLoad::getFilename] Attempting to use an invalid game id. Valid values: 0 - 5, was %d", id);
return gameInfo[id].saveFile;
}
@@ -558,7 +561,7 @@ Common::InSaveFile *SaveLoad::openForLoading(GameId id) {
Common::InSaveFile *load = g_system->getSavefileManager()->openForLoading(getFilename(id));
if (!load)
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::openForLoading - Cannot open savegame for loading: %s", getFilename(id).c_str());
+ debugC(2, kLastExpressDebugSavegame, "Cannot open savegame for loading: %s", getFilename(id).c_str());
return load;
}
@@ -567,7 +570,7 @@ Common::OutSaveFile *SaveLoad::openForSaving(GameId id) {
Common::OutSaveFile *save = g_system->getSavefileManager()->openForSaving(getFilename(id));
if (!save)
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::openForSaving - Cannot open savegame for writing: %s", getFilename(id).c_str());
+ debugC(2, kLastExpressDebugSavegame, "Cannot open savegame for writing: %s", getFilename(id).c_str());
return save;
}
diff --git a/engines/lastexpress/game/savepoint.cpp b/engines/lastexpress/game/savepoint.cpp
index 7ec7c241e9..64ae26c2be 100644
--- a/engines/lastexpress/game/savepoint.cpp
+++ b/engines/lastexpress/game/savepoint.cpp
@@ -128,17 +128,17 @@ void SavePoints::addData(EntityIndex entity, ActionIndex action, uint32 param) {
//////////////////////////////////////////////////////////////////////////
void SavePoints::setCallback(EntityIndex index, Entity::Callback *callback) {
if (index >= 40)
- error("SavePoints::setCallback - attempting to use an invalid entity index. Valid values 0-39, was %d", index);
+ error("[SavePoints::setCallback] Attempting to use an invalid entity index. Valid values 0-39, was %d", index);
if (!callback || !callback->isValid())
- error("SavePoints::setCallback - attempting to set an invalid callback for entity %s", ENTITY_NAME(index));
+ error("[SavePoints::setCallback] Attempting to set an invalid callback for entity %s", ENTITY_NAME(index));
_callbacks[index] = callback;
}
Entity::Callback *SavePoints::getCallback(EntityIndex index) const {
if (index >= 40)
- error("SavePoints::getCallback - attempting to use an invalid entity index. Valid values 0-39, was %d", index);
+ error("[SavePoints::getCallback] Attempting to use an invalid entity index. Valid values 0-39, was %d", index);
return _callbacks[index];
}
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index e830b1d128..b886951e0b 100644
--- a/engines/lastexpress/game/scenes.cpp
+++ b/engines/lastexpress/game/scenes.cpp
@@ -31,9 +31,11 @@
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/graphics.h"
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -79,12 +81,12 @@ void SceneManager::loadSceneDataFile(ArchiveIndex archive) {
case kArchiveCd2:
case kArchiveCd3:
if (!_sceneLoader->load(getArchive(Common::String::format("CD%iTRAIN.DAT", archive))))
- error("SceneManager::loadSceneDataFile: cannot load data file CD%iTRAIN.DAT", archive);
+ error("[SceneManager::loadSceneDataFile] Cannot load data file CD%iTRAIN.DAT", archive);
break;
default:
case kArchiveAll:
- error("SceneManager::loadSceneDataFile: Invalid archive index (must be [1-3], was %d", archive);
+ error("[SceneManager::loadSceneDataFile] Invalid archive index (must be [1-3], was %d", archive);
break;
}
}
@@ -462,7 +464,7 @@ bool SceneManager::checkPosition(SceneIndex index, CheckPositionType type) const
switch (type) {
default:
- error("SceneManager::checkPosition: Invalid position type: %d", type);
+ error("[SceneManager::checkPosition] Invalid position type: %d", type);
case kCheckPositionLookingUp:
return isInSleepingCar && (position >= 1 && position <= 19);
@@ -1057,9 +1059,9 @@ void SceneManager::preProcessScene(SceneIndex *index) {
// Sound processing
Scene *newScene = getScenes()->get(*index);
- if (getSound()->isBuffered(kEntityTables4)) {
+ if (getSoundQueue()->isBuffered(kEntityTables4)) {
if (newScene->type != Scene::kTypeReadText || newScene->param1)
- getSound()->processEntry(kEntityTables4);
+ getSoundQueue()->processEntry(kEntityTables4);
}
// Cleanup beetle sequences
@@ -1089,8 +1091,8 @@ void SceneManager::postProcessScene() {
if (getFlags()->mouseRightClick)
break;
- getSound()->updateQueue();
- getSound()->updateSubtitles();
+ getSoundQueue()->updateQueue();
+ getSoundQueue()->updateSubtitles();
}
}
@@ -1132,7 +1134,7 @@ void SceneManager::postProcessScene() {
}
if (progress)
- getSound()->excuseMe((progress == 1) ? entities[0] : entities[rnd(progress)], kEntityPlayer, SoundManager::kFlagDefault);
+ getSound()->excuseMe((progress == 1) ? entities[0] : entities[rnd(progress)], kEntityPlayer, kFlagDefault);
}
if (hotspot->scene)
@@ -1157,8 +1159,8 @@ void SceneManager::postProcessScene() {
if (getState()->time >= kTimeCityGalanta || getProgress().field_18 == 4)
break;
- getSound()->processEntry(SoundManager::kSoundType7);
- getSound()->playSound(kEntityTrain, "LIB050", SoundManager::kFlagDefault);
+ getSoundQueue()->processEntry(kSoundType7);
+ getSound()->playSound(kEntityTrain, "LIB050", kFlagDefault);
switch (getProgress().chapter) {
default:
diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h
deleted file mode 100644
index ddafc21829..0000000000
--- a/engines/lastexpress/game/sound.h
+++ /dev/null
@@ -1,389 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef LASTEXPRESS_SOUND_H
-#define LASTEXPRESS_SOUND_H
-
-/*
-
- Sound entry: 68 bytes (this is what appears in the savegames)
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - entity
- uint32 {4} - ??
- uint32 {4} - ??
- char {16} - name 1
- char {16} - name 2
-
- Sound queue entry: 120 bytes
- uint16 {2} - status
- byte {1} - ??
- byte {1} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - file data pointer
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - archive structure pointer
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - ??
- uint32 {4} - entity
- uint32 {4} - ??
- uint32 {4} - ??
- char {16} - name 1
- char {16} - name 2
- uint32 {4} - pointer to next entry in the queue
- uint32 {4} - subtitle data pointer
-
-*/
-
-#include "lastexpress/data/snd.h"
-#include "lastexpress/data/subtitle.h"
-
-#include "lastexpress/shared.h"
-
-#include "lastexpress/helpers.h"
-
-#include "common/list.h"
-#include "common/mutex.h"
-#include "common/system.h"
-#include "common/serializer.h"
-
-namespace LastExpress {
-
-class LastExpressEngine;
-class SubtitleManager;
-
-class SoundManager : Common::Serializable {
-public:
- enum SoundType {
- kSoundTypeNone = 0,
- kSoundType1,
- kSoundType2,
- kSoundType3,
- kSoundType4,
- kSoundType5,
- kSoundType6,
- kSoundType7,
- kSoundType8,
- kSoundType9,
- kSoundType10,
- kSoundType11,
- kSoundType12,
- kSoundType13,
- kSoundType14,
- kSoundType15,
- kSoundType16
- };
-
- enum FlagType {
- kFlagInvalid = -1,
- kFlagNone = 0x0,
- kFlag2 = 0x2,
- kFlag3 = 0x3,
- kFlag4 = 0x4,
- kFlag5 = 0x5,
- kFlag6 = 0x6,
- kFlag7 = 0x7,
- kFlag8 = 0x8,
- kFlag9 = 0x9,
- kFlag10 = 0xA,
- kFlag11 = 0xB,
- kFlag12 = 0xC,
- kFlag13 = 0xD,
- kFlag14 = 0xE,
- kFlag15 = 0xF,
- kFlagDefault = 0x10,
-
- kFlagType1_2 = 0x1000000,
- kFlagSteam = 0x1001007,
- kFlagType13 = 0x3000000,
- kFlagMenuClock = 0x3080010,
- kFlagType7 = 0x4000000,
- kFlagType11 = 0x5000000,
- kFlagMusic = 0x5000010,
- kFlagType3 = 0x6000000,
- kFlagLoop = 0x6001008,
- kFlagType9 = 0x7000000
- };
-
- SoundManager(LastExpressEngine *engine);
- ~SoundManager();
-
- // Timer
- void handleTimer();
-
- // State
- void resetState() { _state |= kSoundType1; }
-
- // Sound queue
- void updateQueue();
- void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone);
- void clearQueue();
-
- // Subtitles
- void updateSubtitles();
-
- // Entry
- bool isBuffered(Common::String filename, bool testForEntity = false);
- bool isBuffered(EntityIndex entity);
- void setupEntry(SoundType type, EntityIndex index);
- void processEntry(EntityIndex entity);
- void processEntry(SoundType type);
- void processEntry(Common::String filename);
- void processEntries();
- void removeFromQueue(Common::String filename);
- void removeFromQueue(EntityIndex entity);
- uint32 getEntryTime(EntityIndex index);
-
- // Misc
- void unknownFunction4();
- void clearStatus();
-
- // Sound playing
- void playSound(EntityIndex entity, Common::String filename, FlagType flag = kFlagInvalid, byte a4 = 0);
- bool playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4 = 0);
- void playSoundEvent(EntityIndex entity, byte action, byte a3 = 0);
- void playDialog(EntityIndex entity, EntityIndex entityDialog, FlagType flag, byte a4);
- void playSteam(CityIndex index);
- void playFightSound(byte action, byte a4);
- void playLocomotiveSound();
- void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
-
- // Dialog & Letters
- void readText(int id);
- const char *getDialogName(EntityIndex entity) const;
-
- // Sound bites
- void excuseMe(EntityIndex entity, EntityIndex entity2 = kEntityPlayer, FlagType flag = kFlagNone);
- void excuseMeCath();
- const char *justCheckingCath() const;
- const char *wrongDoorCath() const;
- const char *justAMinuteCath() const;
-
- // FLags
- SoundManager::FlagType getSoundFlag(EntityIndex index) const;
-
- // Debug
- void stopAllSound();
-
- // Serializable
- void saveLoadWithSerializer(Common::Serializer &ser);
- uint32 count();
-
-private:
- typedef int32 *SoundBuffer;
-
- enum SoundStatus {
- kSoundStatus_20 = 0x20,
- kSoundStatus_40 = 0x40,
- kSoundStatus_180 = 0x180,
- kSoundStatusRemoved = 0x200,
- kSoundStatus_400 = 0x400,
-
- kSoundStatus_8000 = 0x8000,
- kSoundStatus_20000 = 0x20000,
- kSoundStatus_100000 = 0x100000,
- kSoundStatus_40000000 = 0x40000000,
-
- kSoundStatusClear0 = 0x10,
- kSoundStatusClear1 = 0x1F,
- kSoundStatusClear2 = 0x80,
- kSoundStatusClear3 = 0x200,
- kSoundStatusClear4 = 0x800,
- kSoundStatusClearAll = 0xFFFFFFE0
- };
-
- enum SoundState {
- kSoundState0 = 0,
- kSoundState1 = 1,
- kSoundState2 = 2
- };
-
- union SoundStatusUnion {
- uint32 status;
- byte status1;
- byte status2;
- byte status3;
- byte status4;
-
- SoundStatusUnion() {
- status = 0;
- }
- };
-
- struct SubtitleEntry;
-
- struct SoundEntry {
- SoundStatusUnion status;
- SoundType type; // int
- //int field_8;
- //int field_C;
- int processedFrameCount;
- void *soundData;
- //int field_18;
- int field_1C;
- uint32 time;
- //int field_24;
- //int field_28;
- Common::SeekableReadStream *stream; // int
- //int field_30;
- int field_34;
- int field_38;
- int field_3C;
- int field_40;
- EntityIndex entity;
- int field_48;
- uint32 field_4C;
- Common::String name1; //char[16];
- Common::String name2; //char[16];
- //int next; // offset to the next structure in the list (not used)
- SubtitleEntry *subtitle;
-
- // Sound stream
- StreamedSound *soundStream;
-
- SoundEntry() {
- status.status = 0;
- type = kSoundTypeNone;
-
- processedFrameCount = 0;
- soundData = NULL;
-
- field_1C = 0;
- time = 0;
-
- stream = NULL;
-
- field_34 = 0;
- field_38 = 0;
- field_3C = 0;
- field_40 = 0;
- entity = kEntityPlayer;
- field_48 = 0;
- field_4C = 0;
-
- subtitle = NULL;
-
- soundStream = NULL;
- }
-
- ~SoundEntry() {
- // Entries that have been queued would have their streamed disposed automatically
- if (!soundStream)
- SAFE_DELETE(stream);
-
- delete soundStream;
- }
- };
-
- struct SubtitleEntry {
- Common::String filename;
- SoundStatusUnion status;
- SoundEntry *sound;
- SubtitleManager *data;
-
- SubtitleEntry() {
- status.status = 0;
- sound = NULL;
- data = NULL;
- }
-
- ~SubtitleEntry() {
- SAFE_DELETE(data);
- }
- };
-
- // Engine
- LastExpressEngine *_engine;
-
- // State flag
- int _state;
- SoundType _currentType;
-
- Common::Mutex _mutex;
-
- // Unknown data
- uint32 _data0;
- uint32 _data1;
- uint32 _data2;
- uint32 _flag;
-
- // Filters
- int32 _buffer[2940]; ///< Static sound buffer
-
- // Compartment warnings by Mertens or Coudert
- uint32 _lastWarning[12];
-
- // Looping sound
- void playLoopingSound();
-
- // Sound entries
- Common::List<SoundEntry *> _soundList; ///< List of all sound entries
- Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer
- void *_soundCacheData;
-
- SoundEntry *getEntry(EntityIndex index);
- SoundEntry *getEntry(Common::String name);
- SoundEntry *getEntry(SoundType type);
-
- void setupEntry(SoundEntry *entry, Common::String name, FlagType flag, int a4);
- void setEntryType(SoundEntry *entry, FlagType flag);
- void setEntryStatus(SoundEntry *entry, FlagType flag) const;
- void setInCache(SoundEntry *entry);
- bool setupCache(SoundEntry *entry);
- void removeFromCache(SoundEntry *entry);
- void loadSoundData(SoundEntry *entry, Common::String name);
-
- void updateEntry(SoundEntry *entry, uint value) const;
- void updateEntryState(SoundEntry *entry) const;
- void resetEntry(SoundEntry *entry) const;
- void removeEntry(SoundEntry *entry);
-
- // Subtitles
- int _drawSubtitles;
- Common::List<SubtitleEntry *> _subtitles;
- SubtitleEntry *_currentSubtitle;
- void showSubtitle(SoundEntry *entry, Common::String filename);
- SubtitleEntry *loadSubtitle(Common::String filename, SoundEntry *soundEntry);
- void loadSubtitleData(SubtitleEntry * entry);
- void setupSubtitleAndDraw(SubtitleEntry *subtitle);
- void drawSubtitle(SubtitleEntry *subtitle);
- void drawSubtitleOnScreen(SubtitleEntry *subtitle);
-
- // Sound filter
- void applyFilter(SoundEntry *entry, SoundBuffer buffer);
-};
-
-} // End of namespace LastExpress
-
-#endif // LASTEXPRESS_SOUND_H
diff --git a/engines/lastexpress/game/state.cpp b/engines/lastexpress/game/state.cpp
index 0cf2ddba40..f3fd9720b1 100644
--- a/engines/lastexpress/game/state.cpp
+++ b/engines/lastexpress/game/state.cpp
@@ -57,7 +57,7 @@ bool State::isNightTime() const {
void State::getHourMinutes(uint32 time, uint8 *hours, uint8 *minutes) {
if (hours == NULL || minutes == NULL)
- error("State::getHourMinutes: invalid parameters passed!");
+ error("[State::getHourMinutes] Invalid parameters passed");
*hours = (uint8)((time % 1296000) / 54000);
*minutes = (uint8)((time % 54000) / 900);
diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h
index 8f71e7d424..c937fdce9f 100644
--- a/engines/lastexpress/game/state.h
+++ b/engines/lastexpress/game/state.h
@@ -325,7 +325,7 @@ public:
switch (index) {
default:
- error("GameProgress::isEqual: invalid index value (was: %d, max:127)", index);
+ error("[GameProgress::getValueName] Invalid index value (was: %d, max:127)", index);
break;
EXPOSE_VALUE(0, field_0);
diff --git a/engines/lastexpress/graphics.cpp b/engines/lastexpress/graphics.cpp
index abbdf2b766..e129457256 100644
--- a/engines/lastexpress/graphics.cpp
+++ b/engines/lastexpress/graphics.cpp
@@ -72,7 +72,7 @@ void GraphicsManager::clear(BackgroundType type) {
void GraphicsManager::clear(BackgroundType type, const Common::Rect &rect) {
switch (type) {
default:
- error("GraphicsManager::clear() - Unknown background type: %d", type);
+ error("[GraphicsManager::clear] Unknown background type: %d", type);
break;
case kBackgroundA:
@@ -105,7 +105,7 @@ bool GraphicsManager::draw(Drawable *drawable, BackgroundType type, bool transit
Graphics::Surface *GraphicsManager::getSurface(BackgroundType type) {
switch (type) {
default:
- error("GraphicsManager::getSurface() - Unknown surface type: %d", type);
+ error("[GraphicsManager::getSurface] Unknown surface type: %d", type);
break;
case kBackgroundA:
@@ -121,7 +121,7 @@ Graphics::Surface *GraphicsManager::getSurface(BackgroundType type) {
return &_inventory;
case kBackgroundAll:
- error("GraphicsManager::getSurface() - cannot return a surface for kBackgroundAll!");
+ error("[GraphicsManager::getSurface] Cannot return a surface for kBackgroundAll");
break;
}
}
diff --git a/engines/lastexpress/helpers.h b/engines/lastexpress/helpers.h
index 594c8b0400..7f3f1e246c 100644
--- a/engines/lastexpress/helpers.h
+++ b/engines/lastexpress/helpers.h
@@ -63,6 +63,7 @@
// Sound
#define getSound() _engine->getSoundManager()
+#define getSoundQueue() _engine->getSoundManager()->getQueue()
// Others
#define getEntityData(entity) getEntities()->getData(entity)
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 6fdd18413b..885ca8b212 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -26,10 +26,13 @@
#include "lastexpress/data/font.h"
#include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
#include "lastexpress/game/scenes.h"
#include "lastexpress/game/state.h"
-#include "lastexpress/game/sound.h"
+
+#include "lastexpress/menu/menu.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
#include "lastexpress/graphics.h"
#include "lastexpress/helpers.h"
@@ -37,6 +40,8 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
+#include "common/error.h"
+#include "common/fs.h"
#include "engines/util.h"
@@ -148,8 +153,8 @@ Common::Error LastExpressEngine::run() {
_menu->show(false, kSavegameTypeIndex, 0);
while (!shouldQuit()) {
- _soundMan->updateQueue();
- _soundMan->updateSubtitles();
+ _soundMan->getQueue()->updateQueue();
+ _soundMan->getQueue()->updateSubtitles();
if (handleEvents())
continue;
@@ -180,7 +185,7 @@ void LastExpressEngine::pollEvents() {
bool LastExpressEngine::handleEvents() {
// Make sure all the subsystems have been initialized
if (!_debugger || !_graphicsMan)
- error("LastExpressEngine::handleEvents: called before the required subsystems have been initialized!");
+ error("[LastExpressEngine::handleEvents] Called before the required subsystems have been initialized");
// Execute stored commands
if (_debugger->hasCommand()) {
@@ -277,7 +282,7 @@ void LastExpressEngine::soundTimer(void *refCon) {
void LastExpressEngine::handleSoundTimer() {
if (_frameCounter & 1)
if (_soundMan)
- _soundMan->handleTimer();
+ _soundMan->getQueue()->handleTimer();
_frameCounter++;
}
@@ -286,22 +291,34 @@ void LastExpressEngine::handleSoundTimer() {
/// Event Handling
///////////////////////////////////////////////////////////////////////////////////
void LastExpressEngine::backupEventHandlers() {
+ if (_eventMouseBackup != NULL || _eventTickBackup != NULL)
+ error("[LastExpressEngine::backupEventHandlers] backup event handlers are already set");
+
_eventMouseBackup = _eventMouse;
_eventTickBackup = _eventTick;
}
void LastExpressEngine::restoreEventHandlers() {
if (_eventMouseBackup == NULL || _eventTickBackup == NULL)
- error("LastExpressEngine::restoreEventHandlers: restore called before backing up the event handlers!");
+ error("[LastExpressEngine::restoreEventHandlers] restore called before backing up the event handlers");
+
+ // Cleanup previous event handlers
+ SAFE_DELETE(_eventMouse);
+ SAFE_DELETE(_eventTick);
_eventMouse = _eventMouseBackup;
_eventTick = _eventTickBackup;
+
+ _eventMouseBackup = NULL;
+ _eventTickBackup = NULL;
}
void LastExpressEngine::setEventHandlers(EventHandler::EventFunction *mouse, EventHandler::EventFunction *tick) {
- // Cleanup previous event handlers
- delete _eventMouse;
- delete _eventTick;
+ if (_eventMouse != _eventMouseBackup)
+ SAFE_DELETE(_eventMouse);
+
+ if (_eventTick != _eventTickBackup)
+ SAFE_DELETE(_eventTick);
_eventMouse = mouse;
_eventTick = tick;
diff --git a/engines/lastexpress/lastexpress.h b/engines/lastexpress/lastexpress.h
index d78bba36f0..f8f38788a0 100644
--- a/engines/lastexpress/lastexpress.h
+++ b/engines/lastexpress/lastexpress.h
@@ -29,11 +29,12 @@
#include "common/random.h"
#include "common/timer.h"
-#include "engines/advancedDetector.h"
#include "engines/engine.h"
#include "graphics/pixelformat.h"
+struct ADGameDescription;
+
/**
* This is the namespace of the LastExpress engine.
*
@@ -101,7 +102,7 @@ public:
void restoreEventHandlers();
void setEventHandlers(EventHandler::EventFunction *eventMouse, EventHandler::EventFunction *eventTick);
- bool isDemo() const { return (bool)(_gameDescription->flags & ADGF_DEMO); }
+ bool isDemo() const;
// Frame Counter
uint32 getFrameCounter() { return _frameCounter; }
diff --git a/engines/lastexpress/menu/clock.cpp b/engines/lastexpress/menu/clock.cpp
new file mode 100644
index 0000000000..dedf045940
--- /dev/null
+++ b/engines/lastexpress/menu/clock.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.
+ *
+ */
+
+#include "lastexpress/menu/clock.h"
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+Clock::Clock(LastExpressEngine *engine) : _engine(engine), _frameMinutes(NULL), _frameHour(NULL), _frameSun(NULL), _frameDate(NULL) {
+ _frameMinutes = new SequenceFrame(loadSequence("eggmin.seq"), 0, true);
+ _frameHour = new SequenceFrame(loadSequence("egghour.seq"), 0, true);
+ _frameSun = new SequenceFrame(loadSequence("sun.seq"), 0, true);
+ _frameDate = new SequenceFrame(loadSequence("datenew.seq"), 0, true);
+}
+
+Clock::~Clock() {
+ SAFE_DELETE(_frameMinutes);
+ SAFE_DELETE(_frameHour);
+ SAFE_DELETE(_frameSun);
+ SAFE_DELETE(_frameDate);
+
+ // Zero passed pointers
+ _engine = NULL;
+}
+
+void Clock::clear() {
+ getScenes()->removeFromQueue(_frameMinutes);
+ getScenes()->removeFromQueue(_frameHour);
+ getScenes()->removeFromQueue(_frameSun);
+ getScenes()->removeFromQueue(_frameDate);
+}
+
+void Clock::draw(uint32 time) {
+ assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
+
+ // Check that sequences have been loaded
+ if (!_frameMinutes || !_frameHour || !_frameSun || !_frameDate)
+ error("[Clock::draw] Clock sequences have not been loaded correctly");
+
+ // Clear existing frames
+ clear();
+
+ // Game starts at: 1037700 = 7:13 p.m. on July 24, 1914
+ // Game ends at: 4941000 = 7:30 p.m. on July 26, 1914
+ // Game lasts for: 3903300 = 2 days + 17 mins = 2897 mins
+
+ // 15 = 1 second
+ // 15 * 60 = 900 = 1 minute
+ // 900 * 60 = 54000 = 1 hour
+ // 54000 * 24 = 1296000 = 1 day
+
+ // Calculate each sequence index from the current time
+
+ uint8 hour = 0;
+ uint8 minute = 0;
+ State::getHourMinutes(time, &hour, &minute);
+ uint32 index_date = 18 * time / 1296000;
+ if (hour == 23)
+ index_date += 18 * minute / 60;
+
+ // Set sequences frames
+ _frameMinutes->setFrame(minute);
+ _frameHour->setFrame((5 * hour + minute / 12) % 60);
+ _frameSun->setFrame((5 * hour + minute / 12) % 120);
+ _frameDate->setFrame((uint16)index_date);
+
+ // Adjust z-order and queue
+ _frameMinutes->getInfo()->location = 1;
+ _frameHour->getInfo()->location = 1;
+ _frameSun->getInfo()->location = 1;
+ _frameDate->getInfo()->location = 1;
+
+ getScenes()->addToQueue(_frameMinutes);
+ getScenes()->addToQueue(_frameHour);
+ getScenes()->addToQueue(_frameSun);
+ getScenes()->addToQueue(_frameDate);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/menu/clock.h b/engines/lastexpress/menu/clock.h
new file mode 100644
index 0000000000..339a18604f
--- /dev/null
+++ b/engines/lastexpress/menu/clock.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 LASTEXPRESS_CLOCK_H
+#define LASTEXPRESS_CLOCK_H
+
+#include "common/scummsys.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SequenceFrame;
+
+class Clock {
+public:
+ explicit Clock(LastExpressEngine *engine);
+ ~Clock();
+
+ void draw(uint32 time);
+ void clear();
+
+private:
+ LastExpressEngine *_engine;
+
+ // Frames
+ SequenceFrame *_frameMinutes;
+ SequenceFrame *_frameHour;
+ SequenceFrame *_frameSun;
+ SequenceFrame *_frameDate;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_CLOCK_H
diff --git a/engines/lastexpress/game/menu.cpp b/engines/lastexpress/menu/menu.cpp
index f9eef26326..f1a8bebe94 100644
--- a/engines/lastexpress/game/menu.cpp
+++ b/engines/lastexpress/menu/menu.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "lastexpress/game/menu.h"
+#include "lastexpress/menu/menu.h"
// Data
#include "lastexpress/data/animation.h"
@@ -28,15 +28,21 @@
#include "lastexpress/data/snd.h"
#include "lastexpress/data/scene.h"
-#include "lastexpress/game/fight.h"
+#include "lastexpress/fight/fight.h"
+
#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/savegame.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/menu/clock.h"
+#include "lastexpress/menu/trainline.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
#include "lastexpress/graphics.h"
#include "lastexpress/helpers.h"
#include "lastexpress/lastexpress.h"
@@ -118,45 +124,6 @@ enum StartMenuTooltips {
//////////////////////////////////////////////////////////////////////////
// DATA
//////////////////////////////////////////////////////////////////////////
-
-// Information about the cities on the train line
-static const struct {
- uint8 frame;
- TimeValue time;
-} _trainCities[31] = {
- {0, kTimeCityParis},
- {9, kTimeCityEpernay},
- {11, kTimeCityChalons},
- {16, kTimeCityBarLeDuc},
- {21, kTimeCityNancy},
- {25, kTimeCityLuneville},
- {35, kTimeCityAvricourt},
- {37, kTimeCityDeutschAvricourt},
- {40, kTimeCityStrasbourg},
- {53, kTimeCityBadenOos},
- {56, kTimeCityKarlsruhe},
- {60, kTimeCityStuttgart},
- {63, kTimeCityGeislingen},
- {66, kTimeCityUlm},
- {68, kTimeCityAugsburg},
- {73, kTimeCityMunich},
- {84, kTimeCitySalzbourg},
- {89, kTimeCityAttnangPuchheim},
- {97, kTimeCityWels},
- {100, kTimeCityLinz},
- {104, kTimeCityAmstetten},
- {111, kTimeCityVienna},
- {120, kTimeCityPoszony},
- {124, kTimeCityGalanta},
- {132, kTimeCityBudapest},
- {148, kTimeCityBelgrade},
- /* Line 1 ends at 150 - line 2 begins at 0 */
- {157, kTimeCityNish},
- {165, kTimeCityTzaribrod},
- {174, kTimeCitySofia},
- {198, kTimeCityAdrianople},
- {210, kTimeCityConstantinople}};
-
static const struct {
TimeValue time;
uint index;
@@ -173,185 +140,6 @@ static const struct {
};
//////////////////////////////////////////////////////////////////////////
-// Clock
-//////////////////////////////////////////////////////////////////////////
-class Clock {
-public:
- explicit Clock(LastExpressEngine *engine);
- ~Clock();
-
- void draw(uint32 time);
- void clear();
-
-private:
- LastExpressEngine *_engine;
-
- // Frames
- SequenceFrame *_frameMinutes;
- SequenceFrame *_frameHour;
- SequenceFrame *_frameSun;
- SequenceFrame *_frameDate;
-};
-
-Clock::Clock(LastExpressEngine *engine) : _engine(engine), _frameMinutes(NULL), _frameHour(NULL), _frameSun(NULL), _frameDate(NULL) {
- _frameMinutes = new SequenceFrame(loadSequence("eggmin.seq"), 0, true);
- _frameHour = new SequenceFrame(loadSequence("egghour.seq"), 0, true);
- _frameSun = new SequenceFrame(loadSequence("sun.seq"), 0, true);
- _frameDate = new SequenceFrame(loadSequence("datenew.seq"), 0, true);
-}
-
-Clock::~Clock() {
- SAFE_DELETE(_frameMinutes);
- SAFE_DELETE(_frameHour);
- SAFE_DELETE(_frameSun);
- SAFE_DELETE(_frameDate);
-
- // Zero passed pointers
- _engine = NULL;
-}
-
-void Clock::clear() {
- getScenes()->removeFromQueue(_frameMinutes);
- getScenes()->removeFromQueue(_frameHour);
- getScenes()->removeFromQueue(_frameSun);
- getScenes()->removeFromQueue(_frameDate);
-}
-
-void Clock::draw(uint32 time) {
- assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
-
- // Check that sequences have been loaded
- if (!_frameMinutes || !_frameHour || !_frameSun || !_frameDate)
- error("Clock::process: clock sequences have not been loaded correctly!");
-
- // Clear existing frames
- clear();
-
- // Game starts at: 1037700 = 7:13 p.m. on July 24, 1914
- // Game ends at: 4941000 = 7:30 p.m. on July 26, 1914
- // Game lasts for: 3903300 = 2 days + 17 mins = 2897 mins
-
- // 15 = 1 second
- // 15 * 60 = 900 = 1 minute
- // 900 * 60 = 54000 = 1 hour
- // 54000 * 24 = 1296000 = 1 day
-
- // Calculate each sequence index from the current time
-
- uint8 hour = 0;
- uint8 minute = 0;
- State::getHourMinutes(time, &hour, &minute);
- uint32 index_date = 18 * time / 1296000;
- if (hour == 23)
- index_date += 18 * minute / 60;
-
- // Set sequences frames
- _frameMinutes->setFrame(minute);
- _frameHour->setFrame((5 * hour + minute / 12) % 60);
- _frameSun->setFrame((5 * hour + minute / 12) % 120);
- _frameDate->setFrame((uint16)index_date);
-
- // Adjust z-order and queue
- _frameMinutes->getInfo()->location = 1;
- _frameHour->getInfo()->location = 1;
- _frameSun->getInfo()->location = 1;
- _frameDate->getInfo()->location = 1;
-
- getScenes()->addToQueue(_frameMinutes);
- getScenes()->addToQueue(_frameHour);
- getScenes()->addToQueue(_frameSun);
- getScenes()->addToQueue(_frameDate);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// TrainLine
-//////////////////////////////////////////////////////////////////////////
-class TrainLine {
-public:
- explicit TrainLine(LastExpressEngine *engine);
- ~TrainLine();
-
- void draw(uint32 time);
- void clear();
-
-private:
- LastExpressEngine *_engine;
-
- // Frames
- SequenceFrame *_frameLine1;
- SequenceFrame *_frameLine2;
-};
-
-TrainLine::TrainLine(LastExpressEngine *engine) : _engine(engine), _frameLine1(NULL), _frameLine2(NULL) {
- _frameLine1 = new SequenceFrame(loadSequence("line1.seq"), 0, true);
- _frameLine2 = new SequenceFrame(loadSequence("line2.seq"), 0, true);
-}
-
-TrainLine::~TrainLine() {
- SAFE_DELETE(_frameLine1);
- SAFE_DELETE(_frameLine2);
-
- // Zero passed pointers
- _engine = NULL;
-}
-
-void TrainLine::clear() {
- getScenes()->removeFromQueue(_frameLine1);
- getScenes()->removeFromQueue(_frameLine2);
-}
-
-// Draw the train line at the time
-// line1: 150 frames (=> Belgrade)
-// line2: 61 frames (=> Constantinople)
-void TrainLine::draw(uint32 time) {
- assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
-
- // Check that sequences have been loaded
- if (!_frameLine1 || !_frameLine2)
- error("TrainLine::process: Line sequences have not been loaded correctly!");
-
- // Clear existing frames
- clear();
-
- // Get the index of the last city the train has visited
- uint index = 0;
- for (uint i = 0; i < ARRAYSIZE(_trainCities); i++)
- if ((uint32)_trainCities[i].time <= time)
- index = i;
-
- uint16 frame;
- if (time > (uint32)_trainCities[index].time) {
- // Interpolate linearly to use a frame between the cities
- uint8 diffFrames = _trainCities[index + 1].frame - _trainCities[index].frame;
- uint diffTimeCities = (uint)(_trainCities[index + 1].time - _trainCities[index].time);
- uint traveledTime = (time - (uint)_trainCities[index].time);
- frame = (uint16)(_trainCities[index].frame + (traveledTime * diffFrames) / diffTimeCities);
- } else {
- // Exactly on the city
- frame = _trainCities[index].frame;
- }
-
- // Set frame, z-order and queue
- if (frame < 150) {
- _frameLine1->setFrame(frame);
-
- _frameLine1->getInfo()->location = 1;
- getScenes()->addToQueue(_frameLine1);
- } else {
- // We passed Belgrade
- _frameLine1->setFrame(149);
- _frameLine2->setFrame(frame - 150);
-
- _frameLine1->getInfo()->location = 1;
- _frameLine2->getInfo()->location = 1;
-
- getScenes()->addToQueue(_frameLine1);
- getScenes()->addToQueue(_frameLine2);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////
Menu::Menu(LastExpressEngine *engine) : _engine(engine),
@@ -528,7 +316,7 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) {
getFlags()->mouseRightClick = false;
// Play intro music
- getSound()->playSoundWithSubtitles("MUS001.SND", SoundManager::kFlagMusic, kEntityPlayer);
+ getSound()->playSoundWithSubtitles("MUS001.SND", kFlagMusic, kEntityPlayer);
// Show The Smoking Car logo
if (animation.load(getArchive("1931.nis")))
@@ -539,7 +327,7 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) {
} else {
// Only show the quick intro
if (!_hasShownStartScreen) {
- getSound()->playSoundWithSubtitles("MUS018.SND", SoundManager::kFlagMusic, kEntityPlayer);
+ getSound()->playSoundWithSubtitles("MUS018.SND", kFlagMusic, kEntityPlayer);
getScenes()->loadScene(kSceneStartScreen);
// Original game waits 60 frames and loops Sound::unknownFunction1 unless the right button is pressed
@@ -550,7 +338,7 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) {
if (getFlags()->mouseRightClick)
break;
- getSound()->updateQueue();
+ getSoundQueue()->updateQueue();
}
}
}
@@ -562,10 +350,10 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) {
init(doSavegame, type, value);
// Setup sound
- getSound()->unknownFunction4();
- getSound()->resetQueue(SoundManager::kSoundType11, SoundManager::kSoundType13);
- if (getSound()->isBuffered("TIMER"))
- getSound()->removeFromQueue("TIMER");
+ getSoundQueue()->resetQueue();
+ getSoundQueue()->resetQueue(kSoundType11, kSoundType13);
+ if (getSoundQueue()->isBuffered("TIMER"))
+ getSoundQueue()->removeFromQueue("TIMER");
// Init flags & misc
_isShowingCredits = false;
@@ -625,13 +413,13 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
if (clicked) {
showFrame(kOverlayButtons, kButtonQuitPushed, true);
- getSound()->clearStatus();
- getSound()->updateQueue();
+ getSoundQueue()->clearStatus();
+ getSoundQueue()->updateQueue();
getSound()->playSound(kEntityPlayer, "LIB046");
// FIXME uncomment when sound queue is properly implemented
- /*while (getSound()->isBuffered("LIB046"))
- getSound()->updateQueue();*/
+ /*while (getSoundQueue()->isBuffered("LIB046"))
+ getSoundQueue()->updateQueue();*/
getFlags()->shouldRedraw = false;
@@ -698,7 +486,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
setLogicEventHandlers();
if (_index) {
- getSound()->processEntry(SoundManager::kSoundType11);
+ getSoundQueue()->processEntry(kSoundType11);
} else {
if (!getFlags()->mouseRightClick) {
getScenes()->loadScene((SceneIndex)(5 * _gameId + 3));
@@ -710,7 +498,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
getScenes()->loadScene((SceneIndex)(5 * _gameId + 5));
if (!getFlags()->mouseRightClick) {
- getSound()->processEntry(SoundManager::kSoundType11);
+ getSoundQueue()->processEntry(kSoundType11);
// Show intro
Animation animation;
@@ -726,7 +514,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
if (!getEvent(kEventIntro)) {
getEvent(kEventIntro) = 1;
- getSound()->processEntry(SoundManager::kSoundType11);
+ getSoundQueue()->processEntry(kSoundType11);
}
}
@@ -921,7 +709,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
while (nextFrameCount > getFrameCount()) {
_engine->pollEvents();
- getSound()->updateQueue();
+ getSoundQueue()->updateQueue();
}
} else {
showFrame(kOverlayButtons, kButtonVolumeDown, true);
@@ -956,7 +744,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
while (nextFrameCount > getFrameCount()) {
_engine->pollEvents();
- getSound()->updateQueue();
+ getSoundQueue()->updateQueue();
}
} else {
showFrame(kOverlayButtons, kButtonVolumeUp, true);
@@ -1072,7 +860,7 @@ void Menu::init(bool doSavegame, SavegameType type, uint32 value) {
useSameIndex = false;
// TODO remove existing savegame and reset index & savegame name
- warning("Menu::initGame: not implemented!");
+ warning("[Menu::initGame] Not implemented");
}
doSavegame = false;
@@ -1331,10 +1119,10 @@ void Menu::updateTime(uint32 time) {
_currentTime = time;
if (_time != time) {
- if (getSound()->isBuffered(kEntityChapters))
- getSound()->removeFromQueue(kEntityChapters);
+ if (getSoundQueue()->isBuffered(kEntityChapters))
+ getSoundQueue()->removeFromQueue(kEntityChapters);
- getSound()->playSoundWithSubtitles((_currentTime >= _time) ? "LIB042" : "LIB041", SoundManager::kFlagMenuClock, kEntityChapters);
+ getSound()->playSoundWithSubtitles((_currentTime >= _time) ? "LIB042" : "LIB041", kFlagMenuClock, kEntityChapters);
adjustIndex(_currentTime, _time, false);
}
}
@@ -1463,8 +1251,8 @@ void Menu::adjustTime() {
_time = _currentTime;
}
- if (_currentTime == _time && getSound()->isBuffered(kEntityChapters))
- getSound()->removeFromQueue(kEntityChapters);
+ if (_currentTime == _time && getSoundQueue()->isBuffered(kEntityChapters))
+ getSoundQueue()->removeFromQueue(kEntityChapters);
_clock->draw(_time);
_trainLine->draw(_time);
diff --git a/engines/lastexpress/game/menu.h b/engines/lastexpress/menu/menu.h
index 4b84c065cb..4b84c065cb 100644
--- a/engines/lastexpress/game/menu.h
+++ b/engines/lastexpress/menu/menu.h
diff --git a/engines/lastexpress/menu/trainline.cpp b/engines/lastexpress/menu/trainline.cpp
new file mode 100644
index 0000000000..f819776163
--- /dev/null
+++ b/engines/lastexpress/menu/trainline.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 "lastexpress/menu/trainline.h"
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/game/scenes.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+// Information about the cities on the train line
+static const struct {
+ uint8 frame;
+ TimeValue time;
+} _trainCities[31] = {
+ {0, kTimeCityParis},
+ {9, kTimeCityEpernay},
+ {11, kTimeCityChalons},
+ {16, kTimeCityBarLeDuc},
+ {21, kTimeCityNancy},
+ {25, kTimeCityLuneville},
+ {35, kTimeCityAvricourt},
+ {37, kTimeCityDeutschAvricourt},
+ {40, kTimeCityStrasbourg},
+ {53, kTimeCityBadenOos},
+ {56, kTimeCityKarlsruhe},
+ {60, kTimeCityStuttgart},
+ {63, kTimeCityGeislingen},
+ {66, kTimeCityUlm},
+ {68, kTimeCityAugsburg},
+ {73, kTimeCityMunich},
+ {84, kTimeCitySalzbourg},
+ {89, kTimeCityAttnangPuchheim},
+ {97, kTimeCityWels},
+ {100, kTimeCityLinz},
+ {104, kTimeCityAmstetten},
+ {111, kTimeCityVienna},
+ {120, kTimeCityPoszony},
+ {124, kTimeCityGalanta},
+ {132, kTimeCityBudapest},
+ {148, kTimeCityBelgrade},
+ /* Line 1 ends at 150 - line 2 begins at 0 */
+ {157, kTimeCityNish},
+ {165, kTimeCityTzaribrod},
+ {174, kTimeCitySofia},
+ {198, kTimeCityAdrianople},
+ {210, kTimeCityConstantinople}
+};
+
+TrainLine::TrainLine(LastExpressEngine *engine) : _engine(engine), _frameLine1(NULL), _frameLine2(NULL) {
+ _frameLine1 = new SequenceFrame(loadSequence("line1.seq"), 0, true);
+ _frameLine2 = new SequenceFrame(loadSequence("line2.seq"), 0, true);
+}
+
+TrainLine::~TrainLine() {
+ SAFE_DELETE(_frameLine1);
+ SAFE_DELETE(_frameLine2);
+
+ // Zero passed pointers
+ _engine = NULL;
+}
+
+void TrainLine::clear() {
+ getScenes()->removeFromQueue(_frameLine1);
+ getScenes()->removeFromQueue(_frameLine2);
+}
+
+// Draw the train line at the time
+// line1: 150 frames (=> Belgrade)
+// line2: 61 frames (=> Constantinople)
+void TrainLine::draw(uint32 time) {
+ assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
+
+ // Check that sequences have been loaded
+ if (!_frameLine1 || !_frameLine2)
+ error("[TrainLine::draw] Line sequences have not been loaded correctly");
+
+ // Clear existing frames
+ clear();
+
+ // Get the index of the last city the train has visited
+ uint index = 0;
+ for (uint i = 0; i < ARRAYSIZE(_trainCities); i++)
+ if ((uint32)_trainCities[i].time <= time)
+ index = i;
+
+ uint16 frame;
+ if (time > (uint32)_trainCities[index].time) {
+ // Interpolate linearly to use a frame between the cities
+ uint8 diffFrames = _trainCities[index + 1].frame - _trainCities[index].frame;
+ uint diffTimeCities = (uint)(_trainCities[index + 1].time - _trainCities[index].time);
+ uint traveledTime = (time - (uint)_trainCities[index].time);
+ frame = (uint16)(_trainCities[index].frame + (traveledTime * diffFrames) / diffTimeCities);
+ } else {
+ // Exactly on the city
+ frame = _trainCities[index].frame;
+ }
+
+ // Set frame, z-order and queue
+ if (frame < 150) {
+ _frameLine1->setFrame(frame);
+
+ _frameLine1->getInfo()->location = 1;
+ getScenes()->addToQueue(_frameLine1);
+ } else {
+ // We passed Belgrade
+ _frameLine1->setFrame(149);
+ _frameLine2->setFrame(frame - 150);
+
+ _frameLine1->getInfo()->location = 1;
+ _frameLine2->getInfo()->location = 1;
+
+ getScenes()->addToQueue(_frameLine1);
+ getScenes()->addToQueue(_frameLine2);
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/menu/trainline.h b/engines/lastexpress/menu/trainline.h
new file mode 100644
index 0000000000..af6a121e9c
--- /dev/null
+++ b/engines/lastexpress/menu/trainline.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 LASTEXPRESS_TRAINLINE_H
+#define LASTEXPRESS_TRAINLINE_H
+
+#include "common/scummsys.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SequenceFrame;
+
+class TrainLine {
+public:
+ explicit TrainLine(LastExpressEngine *engine);
+ ~TrainLine();
+
+ void draw(uint32 time);
+ void clear();
+
+private:
+ LastExpressEngine *_engine;
+
+ // Frames
+ SequenceFrame *_frameLine1;
+ SequenceFrame *_frameLine2;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_TRAINLINE_H
diff --git a/engines/lastexpress/module.mk b/engines/lastexpress/module.mk
index 12fbb4f85b..a11a7c4b67 100644
--- a/engines/lastexpress/module.mk
+++ b/engines/lastexpress/module.mk
@@ -45,19 +45,29 @@ MODULE_OBJS := \
entities/verges.o \
entities/vesna.o \
entities/yasmin.o \
+ fight/fight.o \
+ fight/fighter.o \
+ fight/fighter_anna.o \
+ fight/fighter_ivo.o \
+ fight/fighter_milos.o \
+ fight/fighter_salko.o \
+ fight/fighter_vesna.o \
game/action.o \
game/beetle.o \
game/entities.o \
- game/fight.o \
game/inventory.o \
game/logic.o \
- game/menu.o \
game/object.o \
game/savegame.o \
game/savepoint.o \
game/scenes.o \
- game/sound.o \
game/state.o \
+ menu/clock.o \
+ menu/menu.o \
+ menu/trainline.o \
+ sound/entry.o \
+ sound/queue.o \
+ sound/sound.o \
debug.o \
detection.o \
graphics.o \
diff --git a/engines/lastexpress/resource.cpp b/engines/lastexpress/resource.cpp
index f376a3a299..3910aaa010 100644
--- a/engines/lastexpress/resource.cpp
+++ b/engines/lastexpress/resource.cpp
@@ -52,7 +52,7 @@ bool ResourceManager::isArchivePresent(ArchiveIndex type) {
switch (type) {
default:
case kArchiveAll:
- error("ResourceManager::isArchivePresent: Only checks for single CDs are valid!");
+ error("[ResourceManager::isArchivePresent] Only checks for single CDs are valid");
case kArchiveCd1:
return Common::File::exists(archiveCD1Path);
@@ -134,7 +134,7 @@ Common::SeekableReadStream *ResourceManager::getFileStream(const Common::String
// Check if the file exits in the archive
if (!hasFile(name)) {
//#ifdef _DEBUG
-// error("ResourceManager::getFileStream: cannot open file: %s", name.c_str());
+// error("[ResourceManager::getFileStream] Cannot open file: %s", name.c_str());
//#endif
debugC(2, kLastExpressDebugResource, "Error opening file: %s", name.c_str());
return NULL;
diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h
index 8cebe16d87..69816a3d6c 100644
--- a/engines/lastexpress/shared.h
+++ b/engines/lastexpress/shared.h
@@ -28,6 +28,68 @@
namespace LastExpress {
//////////////////////////////////////////////////////////////////////////
+// Sound
+//////////////////////////////////////////////////////////////////////////
+
+enum SoundType {
+ kSoundTypeNone = 0,
+ kSoundType1,
+ kSoundType2,
+ kSoundType3,
+ kSoundType4,
+ kSoundType5,
+ kSoundType6,
+ kSoundType7,
+ kSoundType8,
+ kSoundType9,
+ kSoundType10,
+ kSoundType11,
+ kSoundType12,
+ kSoundType13,
+ kSoundType14,
+ kSoundType15,
+ kSoundType16
+};
+
+enum SoundFlag {
+ kFlagInvalid = -1,
+ kFlagNone = 0x0,
+ kFlag2 = 0x2,
+ kFlag3 = 0x3,
+ kFlag4 = 0x4,
+ kFlag5 = 0x5,
+ kFlag6 = 0x6,
+ kFlag7 = 0x7,
+ kFlag8 = 0x8,
+ kFlag9 = 0x9,
+ kFlag10 = 0xA,
+ kFlag11 = 0xB,
+ kFlag12 = 0xC,
+ kFlag13 = 0xD,
+ kFlag14 = 0xE,
+ kFlag15 = 0xF,
+ kFlagDefault = 0x10,
+
+ kFlagType1_2 = 0x1000000,
+ kFlagLoopedSound = 0x1001001,
+ kFlagSteam = 0x1001007,
+ kFlagType13 = 0x3000000,
+ kFlagMenuClock = 0x3080010,
+ kFlagType7 = 0x4000000,
+ kFlagType11 = 0x5000000,
+ kFlagMusic = 0x5000010,
+ kFlagType3 = 0x6000000,
+ kFlagLoop = 0x6001008,
+ kFlagType9 = 0x7000000
+};
+
+enum SoundState {
+ kSoundState0 = 0,
+ kSoundState1 = 1,
+ kSoundState2 = 2
+};
+
+//////////////////////////////////////////////////////////////////////////
// Time values
//////////////////////////////////////////////////////////////////////////
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
new file mode 100644
index 0000000000..c34bb4f0cc
--- /dev/null
+++ b/engines/lastexpress/sound/entry.cpp
@@ -0,0 +1,396 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/sound/entry.h"
+
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/graphics.h"
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+#include "common/stream.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// SoundEntry
+//////////////////////////////////////////////////////////////////////////
+SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
+ _type = kSoundTypeNone;
+
+ _currentDataPtr = 0;
+ _soundData = NULL;
+
+ _blockCount = 0;
+ _time = 0;
+
+ _stream = NULL;
+
+ _field_34 = 0;
+ _field_38 = 0;
+ _field_3C = 0;
+ _field_40 = 0;
+ _entity = kEntityPlayer;
+ _field_48 = 0;
+ _priority = 0;
+
+ _subtitle = NULL;
+
+ _soundStream = NULL;
+}
+
+SoundEntry::~SoundEntry() {
+ // Entries that have been queued would have their streamed disposed automatically
+ if (!_soundStream)
+ SAFE_DELETE(_stream);
+
+ delete _soundStream;
+
+ // Zero passed pointers
+ _engine = NULL;
+}
+
+void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
+ _priority = priority;
+ setType(flag);
+ setStatus(flag);
+
+ // Add entry to sound list
+ getSoundQueue()->addToQueue(this);
+
+ // Add entry to cache and load sound data
+ getSoundQueue()->setupCache(this);
+ loadSoundData(name);
+}
+
+void SoundEntry::close() {
+ _status.status |= kSoundStatusRemoved;
+
+ // Loop until ready
+ while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
+ ; // empty loop body
+
+ // The original game remove the entry from the cache here,
+ // but since we are called from within an iterator loop
+ // we will remove the entry there
+ // removeFromCache(entry);
+
+ if (_subtitle) {
+ _subtitle->draw();
+ SAFE_DELETE(_subtitle);
+ }
+
+ if (_entity) {
+ if (_entity == kEntitySteam)
+ getSound()->playLoopingSound(2);
+ else if (_entity != kEntityTrain)
+ getSavePoints()->push(kEntityPlayer, _entity, kActionEndSound);
+ }
+}
+
+void SoundEntry::setType(SoundFlag flag) {
+ switch (flag & kFlagType9) {
+ default:
+ case kFlagNone:
+ _type = getSoundQueue()->getCurrentType();
+ getSoundQueue()->setCurrentType((SoundType)(_type + 1));
+ break;
+
+ case kFlagType1_2: {
+ SoundEntry *previous2 = getSoundQueue()->getEntry(kSoundType2);
+ if (previous2)
+ previous2->update(0);
+
+ SoundEntry *previous = getSoundQueue()->getEntry(kSoundType1);
+ if (previous) {
+ previous->setType(kSoundType2);
+ previous->update(0);
+ }
+
+ _type = kSoundType1;
+ }
+ break;
+
+ case kFlagType3: {
+ SoundEntry *previous = getSoundQueue()->getEntry(kSoundType3);
+ if (previous) {
+ previous->setType(kSoundType4);
+ previous->update(0);
+ }
+
+ _type = kSoundType11;
+ }
+ break;
+
+ case kFlagType7: {
+ SoundEntry *previous = getSoundQueue()->getEntry(kSoundType7);
+ if (previous)
+ previous->setType(kSoundType8);
+
+ _type = kSoundType7;
+ }
+ break;
+
+ case kFlagType9: {
+ SoundEntry *previous = getSoundQueue()->getEntry(kSoundType9);
+ if (previous)
+ previous->setType(kSoundType10);
+
+ _type = kSoundType9;
+ }
+ break;
+
+ case kFlagType11: {
+ SoundEntry *previous = getSoundQueue()->getEntry(kSoundType11);
+ if (previous)
+ previous->setType(kSoundType14);
+
+ _type = kSoundType11;
+ }
+ break;
+
+ case kFlagType13: {
+ SoundEntry *previous = getSoundQueue()->getEntry(kSoundType13);
+ if (previous)
+ previous->setType(kSoundType14);
+
+ _type = kSoundType13;
+ }
+ break;
+ }
+}
+
+void SoundEntry::setStatus(SoundFlag flag) {
+ SoundStatus statusFlag = (SoundStatus)flag;
+ if (!((statusFlag & 0xFF) & kSoundStatusClear1))
+ statusFlag = (SoundStatus)(statusFlag | kSoundStatusClear2);
+
+ if (((statusFlag & 0xFF00) >> 8) & kSoundStatusClear0)
+ _status.status = (uint32)statusFlag;
+ else
+ _status.status = (statusFlag | kSoundStatusClear4);
+}
+
+void SoundEntry::setInCache() {
+ _status.status |= kSoundStatusClear2;
+}
+
+void SoundEntry::loadSoundData(Common::String name) {
+ _name2 = name;
+
+ // Load sound data
+ _stream = getArchive(name);
+
+ if (!_stream)
+ _stream = getArchive("DEFAULT.SND");
+
+ if (_stream) {
+ warning("[Sound::loadSoundData] Not implemented");
+ } else {
+ _status.status = kSoundStatusRemoved;
+ }
+}
+
+void SoundEntry::update(uint val) {
+ if (!(_status.status3 & 64)) {
+ int value2 = val;
+
+ _status.status |= kSoundStatus_100000;
+
+ if (val) {
+ if (getSoundQueue()->getFlag() & 32) {
+ _field_40 = val;
+ value2 = val * 2 + 1;
+ }
+
+ _field_3C = value2;
+ } else {
+ _field_3C = 0;
+ _status.status |= kSoundStatus_40000000;
+ }
+ }
+}
+
+void SoundEntry::updateState() {
+ if (getSoundQueue()->getFlag() & 32) {
+ if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) {
+ uint32 newStatus = _status.status & kSoundStatusClear1;
+
+ _status.status &= kSoundStatusClearAll;
+
+ _field_40 = newStatus;
+ _status.status |= newStatus * 2 + 1;
+ }
+ }
+
+ _status.status |= kSoundStatus_20;
+}
+
+void SoundEntry::reset() {
+ _status.status |= kSoundStatusRemoved;
+ _entity = kEntityPlayer;
+
+ if (_stream) {
+ if (!_soundStream) {
+ SAFE_DELETE(_stream);
+ } else {
+ _soundStream->stop();
+ SAFE_DELETE(_soundStream);
+ }
+
+ _stream = NULL;
+ }
+}
+
+void SoundEntry::showSubtitle(Common::String filename) {
+ _subtitle = new SubtitleEntry(_engine);
+ _subtitle->load(filename, this);
+
+ if (_subtitle->getStatus().status2 & 4) {
+ _subtitle->draw();
+ SAFE_DELETE(_subtitle);
+ } else {
+ _status.status |= kSoundStatus_20000;
+ }
+}
+
+void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
+ if (_name2.matchString("NISSND?") && (_status.status & kFlagType7) != kFlag3) {
+ s.syncAsUint32LE(_status.status);
+ s.syncAsUint32LE(_type);
+ s.syncAsUint32LE(_blockCount); // field_8;
+ s.syncAsUint32LE(_time);
+ s.syncAsUint32LE(_field_34); // field_10;
+ s.syncAsUint32LE(_field_38); // field_14;
+ s.syncAsUint32LE(_entity);
+
+ uint32 delta = (uint32)_field_48 - getSound()->getData2();
+ if (delta > kFlag8)
+ delta = 0;
+ s.syncAsUint32LE(delta);
+
+ s.syncAsUint32LE(_priority);
+
+ char name1[16];
+ strcpy((char *)&name1, _name1.c_str());
+ s.syncBytes((byte *)&name1, 16);
+
+ char name2[16];
+ strcpy((char *)&name2, _name2.c_str());
+ s.syncBytes((byte *)&name2, 16);
+ }
+}
+
+void SoundEntry::loadStream() {
+ if (!_soundStream)
+ _soundStream = new StreamedSound();
+
+ _soundStream->load(_stream);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SubtitleEntry
+//////////////////////////////////////////////////////////////////////////
+SubtitleEntry::SubtitleEntry(LastExpressEngine *engine) : _engine(engine) {
+ _sound = NULL;
+ _data = NULL;
+}
+
+SubtitleEntry::~SubtitleEntry() {
+ SAFE_DELETE(_data);
+}
+
+void SubtitleEntry::load(Common::String filename, SoundEntry *soundEntry) {
+ // Add ourselves to the list of active subtitles
+ getSoundQueue()->addSubtitle(this);
+
+ // Set sound entry and filename
+ _filename = filename + ".SBE";
+ _sound = soundEntry;
+
+ // Load subtitle data
+ if (_engine->getResourceManager()->hasFile(filename)) {
+ if (getSoundQueue()->getSubtitleFlag() & 2)
+ return;
+
+ loadData();
+ } else {
+ _status.status = kSoundStatus_400;
+ }
+}
+
+void SubtitleEntry::loadData() {
+ _data = new SubtitleManager(_engine->getFont());
+ _data->load(getArchive(_filename));
+
+ getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() | 2);
+ getSoundQueue()->setCurrentSubtitle(this);
+}
+
+void SubtitleEntry::setupAndDraw() {
+ if (!_data) {
+ _data = new SubtitleManager(_engine->getFont());
+ _data->load(getArchive(_filename));
+ }
+
+ if (_data->getMaxTime() > _sound->getTime()) {
+ _status.status = kSoundStatus_400;
+ } else {
+ _data->setTime((uint16)_sound->getTime());
+
+ if (getSoundQueue()->getSubtitleFlag() & 1)
+ drawOnScreen();
+ }
+
+ getSoundQueue()->setCurrentSubtitle(this);
+}
+
+void SubtitleEntry::draw() {
+ // Remove ourselves from the queue
+ getSoundQueue()->removeSubtitle(this);
+
+ if (this == getSoundQueue()->getCurrentSubtitle()) {
+ drawOnScreen();
+
+ getSoundQueue()->setCurrentSubtitle(NULL);
+ getSoundQueue()->setSubtitleFlag(0);
+ }
+}
+
+void SubtitleEntry::drawOnScreen() {
+ getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() & -1);
+
+ if (_data == NULL)
+ return;
+
+ if (getSoundQueue()->getSubtitleFlag() & 1)
+ _engine->getGraphicsManager()->draw(_data, GraphicsManager::kBackgroundOverlay);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/sound/entry.h b/engines/lastexpress/sound/entry.h
new file mode 100644
index 0000000000..60795332f8
--- /dev/null
+++ b/engines/lastexpress/sound/entry.h
@@ -0,0 +1,220 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LASTEXPRESS_SOUND_ENTRY_H
+#define LASTEXPRESS_SOUND_ENTRY_H
+
+/*
+ Sound entry: 68 bytes (this is what appears in savegames)
+ uint32 {4} - status
+ uint32 {4} - type
+ uint32 {4} - blockCount
+ uint32 {4} - time
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - entity
+ uint32 {4} - ??
+ uint32 {4} - priority
+ char {16} - name 1
+ char {16} - name 2
+
+ Sound queue entry: 120 bytes
+ uint16 {2} - status
+ byte {1} - type
+ byte {1} - ??
+ uint32 {4} - ??
+ uint32 {4} - currentDataPtr
+ uint32 {4} - soundData
+ uint32 {4} - currentBufferPtr
+ uint32 {4} - blockCount
+ uint32 {4} - time
+ uint32 {4} - size
+ uint32 {4} - ??
+ uint32 {4} - archive structure pointer
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - ??
+ uint32 {4} - entity
+ uint32 {4} - ??
+ uint32 {4} - priority
+ char {16} - name 1
+ char {16} - name 2
+ uint32 {4} - pointer to next entry in the queue
+ uint32 {4} - subtitle data pointer
+*/
+
+#include "lastexpress/data/snd.h"
+#include "lastexpress/data/subtitle.h"
+
+#include "lastexpress/shared.h"
+
+#include "common/serializer.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SubtitleEntry;
+
+enum SoundStatus {
+ kSoundStatus_20 = 0x20,
+ kSoundStatus_40 = 0x40,
+ kSoundStatus_180 = 0x180,
+ kSoundStatusRemoved = 0x200,
+ kSoundStatus_400 = 0x400,
+
+ kSoundStatus_8000 = 0x8000,
+ kSoundStatus_20000 = 0x20000,
+ kSoundStatus_100000 = 0x100000,
+ kSoundStatus_20000000 = 0x20000000,
+ kSoundStatus_40000000 = 0x40000000,
+
+ kSoundStatusClear0 = 0x10,
+ kSoundStatusClear1 = 0x1F,
+ kSoundStatusClear2 = 0x80,
+ kSoundStatusClear3 = 0x200,
+ kSoundStatusClear4 = 0x800,
+ kSoundStatusClearAll = 0xFFFFFFE0
+};
+
+union SoundStatusUnion {
+ uint32 status;
+ byte status1;
+ byte status2;
+ byte status3;
+ byte status4;
+
+ SoundStatusUnion() {
+ status = 0;
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////
+// SoundEntry
+//////////////////////////////////////////////////////////////////////////
+class SoundEntry : Common::Serializable {
+public:
+ SoundEntry(LastExpressEngine *engine);
+ ~SoundEntry();
+
+ void open(Common::String name, SoundFlag flag, int priority);
+ void close();
+
+ void setStatus(SoundFlag flag);
+ void setType(SoundFlag flag);
+ void setInCache();
+ void loadSoundData(Common::String name);
+ void update(uint val);
+ void updateState();
+ void reset();
+
+ void loadStream();
+
+ // Subtitles
+ void showSubtitle(Common::String filename);
+
+ // Serializable
+ void saveLoadWithSerializer(Common::Serializer &ser);
+
+ // Accessors
+ void setStatus(int status) { _status.status = status; }
+ void setType(SoundType type) { _type = type; }
+ void setEntity(EntityIndex entity) { _entity = entity; }
+ void setField48(int val) { _field_48 = val; }
+
+ SoundStatusUnion getStatus() { return _status; }
+ SoundType getType() { return _type; }
+ uint32 getTime() { return _time; }
+ EntityIndex getEntity() { return _entity; }
+ uint32 getPriority() { return _priority; }
+ Common::String getName2() { return _name2; }
+
+ // Streams
+ Common::SeekableReadStream *getStream() { return _stream; }
+ StreamedSound *getStreamedSound() { return _soundStream; }
+
+public:
+ // TODO replace by on-the-fly allocated buffer
+ void *_soundData;
+
+private:
+ LastExpressEngine *_engine;
+
+ SoundStatusUnion _status;
+ SoundType _type; // int
+ //int _data;
+ //int _endOffset;
+ int _currentDataPtr;
+ //int _currentBufferPtr;
+ int _blockCount;
+ uint32 _time;
+ //int _size;
+ //int _field_28;
+ Common::SeekableReadStream *_stream; // int
+ //int _field_30;
+ int _field_34;
+ int _field_38;
+ int _field_3C;
+ int _field_40;
+ EntityIndex _entity;
+ int _field_48;
+ uint32 _priority;
+ Common::String _name1; //char[16];
+ Common::String _name2; //char[16];
+ // original has pointer to the next structure in the list (not used)
+ SubtitleEntry *_subtitle;
+
+ // Sound stream
+ StreamedSound *_soundStream;
+};
+
+//////////////////////////////////////////////////////////////////////////
+// SubtitleEntry
+//////////////////////////////////////////////////////////////////////////
+class SubtitleEntry {
+public:
+ SubtitleEntry(LastExpressEngine *engine);
+ ~SubtitleEntry();
+
+ void load(Common::String filename, SoundEntry *soundEntry);
+ void loadData();
+ void draw();
+ void setupAndDraw();
+ void drawOnScreen();
+
+ // Accessors
+ SoundStatusUnion getStatus() { return _status; }
+ SoundEntry *getSoundEntry() { return _sound; }
+
+private:
+ LastExpressEngine *_engine;
+
+ Common::String _filename;
+ SoundStatusUnion _status;
+ SoundEntry *_sound;
+ SubtitleManager *_data;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SOUND_ENTRY_H
diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp
new file mode 100644
index 0000000000..cbd942f082
--- /dev/null
+++ b/engines/lastexpress/sound/queue.cpp
@@ -0,0 +1,793 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/sound/queue.h"
+
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/sound/entry.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+namespace LastExpress {
+
+#define SOUNDCACHE_ENTRY_SIZE 92160
+#define SOUNDCACHE_MAX_SIZE 6
+
+SoundQueue::SoundQueue(LastExpressEngine *engine) : _engine(engine) {
+ _state = 0;
+ _currentType = kSoundType16;
+ _flag = 0;
+
+ // Cache and filter buffers
+ memset(&_buffer, 0, sizeof(_buffer));
+ _soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE);
+
+ _subtitlesFlag = 0;
+ _currentSubtitle = NULL;
+}
+
+SoundQueue::~SoundQueue() {
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+ SAFE_DELETE(*i);
+ _soundList.clear();
+
+ // Entries in the cache are just pointers to sound list entries
+ _soundCache.clear();
+
+ for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i)
+ SAFE_DELETE(*i);
+ _subtitles.clear();
+
+ _currentSubtitle = NULL;
+
+ free(_soundCacheData);
+
+ // Zero passed pointers
+ _engine = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Timer
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::handleTimer() {
+ Common::StackLock locker(_mutex);
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ SoundEntry *entry = (*i);
+ if (entry->getStream() == NULL) {
+ SAFE_DELETE(*i);
+ i = _soundList.reverse_erase(i);
+ continue;
+ } else if (!entry->getStreamedSound()) {
+ // TODO: stream any sound in the queue after filtering
+ entry->loadStream();
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sound queue management
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::addToQueue(SoundEntry *entry) {
+ _soundList.push_back(entry);
+}
+
+void SoundQueue::removeFromQueue(EntityIndex entity) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(entity);
+ if (entry)
+ entry->reset();
+}
+
+void SoundQueue::removeFromQueue(Common::String filename) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(filename);
+ if (entry)
+ entry->reset();
+}
+
+void SoundQueue::updateQueue() {
+ Common::StackLock locker(_mutex);
+
+ warning("[Sound::updateQueue] Not implemented");
+}
+
+void SoundQueue::resetQueue() {
+ Common::StackLock locker(_mutex);
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ if ((*i)->getType() == kSoundType1) {
+ (*i)->reset();
+ break;
+ }
+ }
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ if ((*i)->getType() == kSoundType2) {
+ (*i)->reset();
+ break;
+ }
+ }
+}
+
+void SoundQueue::resetQueue(SoundType type1, SoundType type2) {
+ if (!type2)
+ type2 = type1;
+
+ Common::StackLock locker(_mutex);
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ if ((*i)->getType() != type1 && (*i)->getType() != type2)
+ (*i)->reset();
+ }
+}
+
+void SoundQueue::clearQueue() {
+ _flag |= 4;
+
+ // FIXME: Wait a while for a flag to be set
+ //for (int i = 0; i < 3000000; i++)
+ // if (_flag & 8)
+ // break;
+
+ _flag |= 8;
+
+ Common::StackLock locker(_mutex);
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ SoundEntry *entry = (*i);
+
+ // Delete entry
+ entry->close();
+ SAFE_DELETE(entry);
+
+ i = _soundList.reverse_erase(i);
+ }
+
+ updateSubtitles();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// State
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::clearStatus() {
+ Common::StackLock locker(_mutex);
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+ (*i)->setStatus((*i)->getStatus().status | kSoundStatusClear3);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Entry management
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::setupEntry(SoundType type, EntityIndex index) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(type);
+ if (entry)
+ entry->setEntity(index);
+}
+
+void SoundQueue::processEntry(EntityIndex entity) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(entity);
+ if (entry) {
+ entry->update(0);
+ entry->setEntity(kEntityPlayer);
+ }
+}
+
+void SoundQueue::processEntry(SoundType type) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(type);
+ if (entry)
+ entry->update(0);
+}
+
+void SoundQueue::processEntry(Common::String filename) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(filename);
+ if (entry) {
+ entry->update(0);
+ entry->setEntity(kEntityPlayer);
+ }
+}
+
+void SoundQueue::processEntries() {
+ _state = 0;
+
+ processEntry(kSoundType1);
+ processEntry(kSoundType2);
+}
+
+SoundEntry *SoundQueue::getEntry(EntityIndex index) {
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ if ((*i)->getEntity() == index)
+ return *i;
+ }
+
+ return NULL;
+}
+
+SoundEntry *SoundQueue::getEntry(Common::String name) {
+ if (!name.contains('.'))
+ name += ".SND";
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ if ((*i)->getName2() == name)
+ return *i;
+ }
+
+ return NULL;
+}
+
+SoundEntry *SoundQueue::getEntry(SoundType type) {
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ if ((*i)->getType() == type)
+ return *i;
+ }
+
+ return NULL;
+}
+
+uint32 SoundQueue::getEntryTime(EntityIndex index) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(index);
+ if (entry)
+ return entry->getTime();
+
+ return 0;
+}
+
+bool SoundQueue::isBuffered(EntityIndex entity) {
+ Common::StackLock locker(_mutex);
+
+ return (getEntry(entity) != NULL);
+}
+
+bool SoundQueue::isBuffered(Common::String filename, bool testForEntity) {
+ Common::StackLock locker(_mutex);
+
+ SoundEntry *entry = getEntry(filename);
+
+ if (testForEntity)
+ return entry != NULL && entry->getEntity() != kEntityPlayer;
+
+ return (entry != NULL);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Subtitles
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::updateSubtitles() {
+ Common::StackLock locker(_mutex);
+
+ uint32 index = 0;
+ SubtitleEntry *subtitle = NULL;
+
+ for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
+ uint32 current_index = 0;
+ SoundEntry *soundEntry = (*i)->getSoundEntry();
+ SoundStatus status = (SoundStatus)soundEntry->getStatus().status;
+
+ if (!(status & kSoundStatus_40)
+ || status & kSoundStatus_180
+ || soundEntry->getTime() == 0
+ || (status & kSoundStatusClear1) < 6
+ || ((getFlags()->nis & 0x8000) && soundEntry->getPriority() < 90)) {
+ current_index = 0;
+ } else {
+ current_index = soundEntry->getPriority() + (status & kSoundStatusClear1);
+
+ if (_currentSubtitle == (*i))
+ current_index += 4;
+ }
+
+ if (index < current_index) {
+ index = current_index;
+ subtitle = (*i);
+ }
+ }
+
+ if (_currentSubtitle == subtitle) {
+ if (subtitle)
+ subtitle->setupAndDraw();
+
+ return;
+ }
+
+ if (_subtitlesFlag & 1)
+ subtitle->drawOnScreen();
+
+ if (subtitle) {
+ subtitle->loadData();
+ subtitle->setupAndDraw();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Cache
+//////////////////////////////////////////////////////////////////////////
+bool SoundQueue::setupCache(SoundEntry *entry) {
+ if (entry->_soundData)
+ return true;
+
+ if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) {
+
+ SoundEntry *cacheEntry = NULL;
+ uint32 size = 1000;
+
+ for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
+ if (!((*i)->getStatus().status & kSoundStatus_180)) {
+ uint32 newSize = (*i)->getPriority() + ((*i)->getStatus().status & kSoundStatusClear1);
+
+ if (newSize < size) {
+ cacheEntry = (*i);
+ size = newSize;
+ }
+ }
+ }
+
+ if (entry->getPriority() <= size)
+ return false;
+
+ if (!cacheEntry)
+ error("[SoundManager::setupCache] Cannot find a valid entry");
+
+ cacheEntry->setInCache();
+
+ // TODO: Wait until the cache entry is ready to be removed
+ while (!(cacheEntry->getStatus().status1 & 1))
+ ;
+
+ if (cacheEntry->_soundData)
+ removeFromCache(cacheEntry);
+
+ _soundCache.push_back(entry);
+ entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
+ } else {
+ _soundCache.push_back(entry);
+ entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
+ }
+
+ return true;
+}
+
+void SoundQueue::removeFromCache(SoundEntry *entry) {
+ for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
+ if ((*i) == entry) {
+ // Remove sound buffer
+ entry->_soundData = NULL;
+
+ // Remove entry from sound cache
+ i = _soundCache.reverse_erase(i);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Savegame
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::saveLoadWithSerializer(Common::Serializer &s) {
+ Common::StackLock locker(_mutex);
+
+ s.syncAsUint32LE(_state);
+ s.syncAsUint32LE(_currentType);
+
+ // Compute the number of entries to save
+ uint32 numEntries = count();
+ s.syncAsUint32LE(numEntries);
+
+ // Save or load each entry data
+ if (s.isSaving()) {
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+ (*i)->saveLoadWithSerializer(s);
+ } else {
+ warning("[Sound::saveLoadWithSerializer] Loading not implemented");
+ s.skip(numEntries * 64);
+ }
+}
+
+
+// FIXME: We probably need another mutex here to protect during the whole savegame process
+// as we could have removed an entry between the time we check the count and the time we
+// save the entries
+uint32 SoundQueue::count() {
+ Common::StackLock locker(_mutex);
+
+ uint32 numEntries = 0;
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+ if ((*i)->getName2().matchString("NISSND?"))
+ ++numEntries;
+
+ return numEntries;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sound filters
+//////////////////////////////////////////////////////////////////////////
+static const int filterData[1424] = {
+ 0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256,
+ 384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0,
+ 192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640,
+ 64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128,
+ 320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576,
+ 704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192,
+ 192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448,
+ 576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832,
+ 320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320,
+ 320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704,
+ 832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448,
+ 448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448,
+ 640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960,
+ 1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576,
+ 576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576,
+ 576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832,
+ 960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088,
+ 1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704,
+ 704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768,
+ 768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960,
+ 1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280,
+ 1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896,
+ 896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896,
+ 896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152,
+ 1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408,
+ 1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600,
+ 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088,
+ 1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088,
+ 1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152,
+ 1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152,
+ 1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408,
+ 1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536,
+ 1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728,
+ 1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856,
+ 1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344,
+ 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408,
+ 1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408,
+ 1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472,
+ 1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664,
+ 1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856,
+ 1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984,
+ 2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176,
+ 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664,
+ 1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664,
+ 1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728,
+ 1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728,
+ 1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984,
+ 2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112,
+ 2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304,
+ 2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432,
+ 1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920,
+ 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984,
+ 1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984,
+ 1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048,
+ 2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240,
+ 2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432,
+ 2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560,
+ 2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752,
+ 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240,
+ 2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240,
+ 2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304,
+ 2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304,
+ 2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560,
+ 2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688,
+ 2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880,
+ 3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008,
+ 2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496,
+ 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560,
+ 2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560,
+ 2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624,
+ 2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816,
+ 2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008,
+ 3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136,
+ 3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328,
+ 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816,
+ 2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816,
+ 2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880,
+ 2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880,
+ 3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136,
+ 3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264,
+ 3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456,
+ 3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584,
+ 3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072,
+ 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136,
+ 3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136,
+ 3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200,
+ 3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392,
+ 3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584,
+ 3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712,
+ 3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904,
+ 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392,
+ 3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392,
+ 3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456,
+ 3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456,
+ 3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712,
+ 3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840,
+ 3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032,
+ 4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160,
+ 3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648,
+ 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712,
+ 3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712,
+ 3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776,
+ 3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968,
+ 4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160,
+ 4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288,
+ 4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480,
+ 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968,
+ 3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968,
+ 3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032,
+ 4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032,
+ 4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288,
+ 4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416,
+ 4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608,
+ 4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736,
+ 4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224,
+ 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288,
+ 4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288,
+ 4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352,
+ 4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544,
+ 4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736,
+ 4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864,
+ 4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056,
+ 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544,
+ 4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544,
+ 4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608,
+ 4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608,
+ 4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864,
+ 4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992,
+ 5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184,
+ 5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312,
+ 4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800,
+ 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864,
+ 4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864,
+ 4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928,
+ 5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120,
+ 5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312,
+ 5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440,
+ 5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632,
+ 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120,
+ 5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120,
+ 5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184,
+ 5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184,
+ 5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440,
+ 5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568,
+ 5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632,
+ 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632,
+ 5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376,
+ 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440,
+ 5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440,
+ 5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504,
+ 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632,
+ 5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632,
+ 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632,
+ 5632
+};
+
+static const int filterData2[1424] = {
+ 0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11,
+ -13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9,
+ -11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5,
+ -7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18,
+ -1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12,
+ 15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4,
+ 7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19,
+ -22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14,
+ -17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5,
+ -8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26,
+ 30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10,
+ 14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27,
+ -31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16,
+ -21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2,
+ -7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25,
+ 31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3,
+ 9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34,
+ -40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17,
+ -24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50,
+ 58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21,
+ 29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55,
+ -63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32,
+ -41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5,
+ -15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50,
+ 61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6,
+ 18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56,
+ -68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20,
+ -34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82,
+ 97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8,
+ 24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74,
+ -90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9,
+ -27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70,
+ 90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130,
+ -150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55,
+ -77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133,
+ 157, 181, -12, -36, -60, -84, -109, -133, -157, -181,
+ 13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93,
+ -120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191,
+ 221, -14, -44, -73, -103, -132, -162, -191, -221, 16,
+ 48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113,
+ -146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232,
+ 268, -17, -53, -89, -125, -160, -196, -232, -268, 19,
+ 58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137,
+ -176, -215, -255, -294, 21, 64, 108, 151, 194, 237,
+ 281, 324, -21, -64, -108, -151, -194, -237, -281, -324,
+ 23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118,
+ -166, -213, -261, -308, -356, 26, 78, 130, 182, 235,
+ 287, 339, 391, -26, -78, -130, -182, -235, -287, -339,
+ -391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86,
+ -143, -201, -258, -316, -373, -431, 31, 94, 158, 221,
+ 284, 347, 411, 474, -31, -94, -158, -221, -284, -347,
+ -411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34,
+ -104, -174, -244, -313, -383, -453, -523, 38, 115, 191,
+ 268, 345, 422, 498, 575, -38, -115, -191, -268, -345,
+ -422, -498, -575, 42, 126, 210, 294, 379, 463, 547,
+ 631, -42, -126, -210, -294, -379, -463, -547, -631,
+ 46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231,
+ -324, -417, -510, -602, -695, 51, 153, 255, 357, 459,
+ 561, 663, 765, -51, -153, -255, -357, -459, -561, -663,
+ -765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168,
+ -280, -392, -505, -617, -729, -841, 61, 185, 308, 432,
+ 555, 679, 802, 926, -61, -185, -308, -432, -555, -679,
+ -802, -926, 68, 204, 340, 476, 612, 748, 884, 1020,
+ -68, -204, -340, -476, -612, -748, -884, -1020, 74,
+ 224, 373, 523, 672, 822, 971, 1121, -74, -224, -373,
+ -523, -672, -822, -971, -1121, 82, 246, 411, 575, 740,
+ 904, 1069, 1233, -82, -246, -411, -575, -740, -904,
+ -1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357,
+ -90, -271, -452, -633, -814, -995, -1176, -1357, 99,
+ 298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497,
+ -696, -895, -1094, -1293, -1492, 109, 328, 547, 766,
+ 985, 1204, 1423, 1642, -109, -328, -547, -766, -985,
+ -1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324,
+ 1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564,
+ -1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132,
+ -397, -662, -927, -1192, -1457, -1722, -1987, 145, 437,
+ 728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728,
+ -1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121,
+ 1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442,
+ -1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940,
+ 2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292,
+ -2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910,
+ -194, -582, -970, -1358, -1746, -2134, -2522, -2910,
+ 213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213,
+ -640, -1066, -1493, -1920, -2347, -2773, -3200, 234,
+ 704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704,
+ -1173, -1643, -2112, -2582, -3051, -3521, 258, 774,
+ 1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291,
+ -1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988,
+ 2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556,
+ -3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436,
+ 4060, 4685, -312, -937, -1561, -2186, -2811, -3436,
+ -4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467,
+ 5154, -343, -1030, -1718, -2405, -3092, -3779, -4467,
+ -5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670,
+ -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670,
+ 415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415,
+ -1247, -2079, -2911, -3742, -4574, -5406, -6238, 457,
+ 1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372,
+ -2287, -3202, -4117, -5032, -5947, -6862, 503, 1509,
+ 2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516,
+ -3522, -4529, -5535, -6542, -7548, 553, 1660, 2767,
+ 3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874,
+ -4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479,
+ 6697, 7915, 9133, -608, -1826, -3044, -4262, -5479,
+ -6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367,
+ 8706, 10046, -669, -2009, -3348, -4688, -6027, -7367,
+ -8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577,
+ 11051, -736, -2210, -3683, -5157, -6630, -8104, -9577,
+ -11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157,
+ -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157,
+ 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891,
+ -2674, -4457, -6240, -8023, -9806, -11589, -13372, 980,
+ 2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941,
+ -4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236,
+ 5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236,
+ -5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559,
+ 5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559,
+ -5933, -8306, -10679, -13052, -15426, -17799, 1305,
+ 3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305,
+ -3915, -6526, -9136, -11747, -14357, -16968, -19578,
+ 1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538,
+ -1435, -4307, -7179, -10051, -12922, -15794, -18666,
+ -21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531,
+ 23690, -1579, -4738, -7896, -11055, -14214, -17373,
+ -20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111,
+ 22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111,
+ -22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022,
+ 24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022,
+ -24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124,
+ 27329, 31533, -2102, -6306, -10511, -14715, -18920,
+ -23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812,
+ 25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812,
+ -25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893,
+ 27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893,
+ -27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183,
+ 30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183,
+ -30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700,
+ 32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700,
+ -32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471,
+ 32767, 32767, 32767, -3385, -10157, -16928, -23700,
+ -30471, -32767, -32767, -32767, 3724, 11172, 18621,
+ 26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621,
+ -26069, -32767, -32767, -32767, -32767, 4095, 12287,
+ 20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287,
+ -20479, -28671, -32767, -32767, -32767, -32767
+};
+
+static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 };
+static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 };
+
+static void soundFilter(byte *data, int16 *buffer, int p1, int p2);
+
+void SoundQueue::applyFilter(SoundEntry *entry, int16 *buffer) {
+ if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) {
+ entry->setStatus(entry->getStatus().status | kSoundStatus_20000000);
+ } else {
+ int variant = entry->getStatus().status & 0x1f;
+
+ soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
+ }
+}
+
+
+static void soundFilter(byte *data, int16 *buffer, int p1, int p2) {
+ int data1, data2, data1p, data2p;
+ byte idx;
+
+ data2 = data[0];
+ data1 = data[1] << 6;
+
+ data += 2;
+
+ for (int count = 0; count < 735; count++) {
+ idx = data[count] >> 4;
+ data1p = filterData[idx + data1];
+ data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767);
+
+ buffer[2 * count] = (p2 * data2p) >> p1;
+
+ idx = data[count] & 0xF;
+
+ data1 = filterData[idx + data1p];
+ data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767);
+ buffer[2 * count + 1] = (p2 * data2) >> p1;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Debug
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::stopAllSound() {
+ Common::StackLock locker(_mutex);
+
+ for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+ (*i)->getStreamedSound()->stop();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/sound/queue.h b/engines/lastexpress/sound/queue.h
new file mode 100644
index 0000000000..3748a266e0
--- /dev/null
+++ b/engines/lastexpress/sound/queue.h
@@ -0,0 +1,131 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LASTEXPRESS_SOUND_QUEUE_H
+#define LASTEXPRESS_SOUND_QUEUE_H
+
+#include "lastexpress/shared.h"
+
+#include "common/array.h"
+#include "common/mutex.h"
+#include "common/serializer.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SoundEntry;
+class SubtitleEntry;
+
+class SoundQueue : Common::Serializable {
+public:
+ SoundQueue(LastExpressEngine *engine);
+ ~SoundQueue();
+
+ // Timer
+ void handleTimer();
+
+ // Queue
+ void addToQueue(SoundEntry *entry);
+ void removeFromQueue(Common::String filename);
+ void removeFromQueue(EntityIndex entity);
+ void updateQueue();
+ void resetQueue();
+ void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone);
+ void clearQueue();
+
+ // State
+ void clearStatus();
+ int getSoundState() { return _state; }
+ void resetState() { resetState(kSoundState1); }
+ void resetState(SoundState state) { _state |= state; }
+
+ // Entries
+ void setupEntry(SoundType type, EntityIndex index);
+ void processEntry(EntityIndex entity);
+ void processEntry(SoundType type);
+ void processEntry(Common::String filename);
+ void processEntries();
+ SoundEntry *getEntry(SoundType type);
+ SoundEntry *getEntry(EntityIndex index);
+ SoundEntry *getEntry(Common::String name);
+ uint32 getEntryTime(EntityIndex index);
+ bool isBuffered(Common::String filename, bool testForEntity = false);
+ bool isBuffered(EntityIndex entity);
+
+ // Subtitles
+ void updateSubtitles();
+ void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); }
+ void removeSubtitle(SubtitleEntry *entry) { _subtitles.remove(entry); }
+ void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
+ SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
+
+ // Cache
+ bool setupCache(SoundEntry *entry);
+
+ // Serializable
+ void saveLoadWithSerializer(Common::Serializer &ser);
+ uint32 count();
+
+ // Accessors
+ uint32 getFlag() { return _flag; }
+ int getSubtitleFlag() { return _subtitlesFlag; }
+ void setSubtitleFlag(int flag) { _subtitlesFlag = flag; }
+ SoundType getCurrentType() { return _currentType; }
+ void setCurrentType(SoundType type) { _currentType = type; }
+
+protected:
+ // Debug
+ void stopAllSound();
+
+private:
+ LastExpressEngine *_engine;
+
+ Common::Mutex _mutex;
+
+ // State & shared data
+ int _state;
+ SoundType _currentType;
+ // TODO: this seems to be a synchronization flag for the sound timer
+ uint32 _flag;
+
+ // Entries
+ Common::List<SoundEntry *> _soundList; ///< List of all sound entries
+ Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer
+ void *_soundCacheData;
+
+ // Subtitles
+ int _subtitlesFlag;
+ Common::List<SubtitleEntry *> _subtitles;
+ SubtitleEntry *_currentSubtitle;
+
+ // Filters
+ int32 _buffer[2940]; ///< Static sound buffer
+
+ void removeFromCache(SoundEntry *entry);
+ void applyFilter(SoundEntry *entry, int16 *buffer);
+
+ friend class Debugger;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SOUND_QUEUE_H
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/sound/sound.cpp
index 3f98ac79ea..c726769495 100644
--- a/engines/lastexpress/game/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -20,15 +20,19 @@
*
*/
-#include "lastexpress/game/sound.h"
+#include "lastexpress/sound/sound.h"
#include "lastexpress/game/action.h"
#include "lastexpress/game/entities.h"
#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/entry.h"
+#include "lastexpress/sound/queue.h"
+
#include "lastexpress/helpers.h"
#include "lastexpress/graphics.h"
#include "lastexpress/lastexpress.h"
@@ -36,11 +40,8 @@
namespace LastExpress {
-#define SOUNDCACHE_ENTRY_SIZE 92160
-#define SOUNDCACHE_MAX_SIZE 6
-
// Letters & messages
-const char *messages[24] = {
+static const char *const messages[24] = {
"",
"TXT1001", // 1
"TXT1001A", // 2
@@ -67,7 +68,7 @@ const char *messages[24] = {
"ENDALRM3" // 65
};
-const char *cities[17] = {
+static const char *const cities[17] = {
"EPERNAY",
"CHALONS",
"BARLEDUC",
@@ -87,7 +88,7 @@ const char *cities[17] = {
"POLICE"
};
-const char *locomotiveSounds[5] = {
+static const char *const locomotiveSounds[5] = {
"ZFX1005",
"ZFX1006",
"ZFX1007",
@@ -95,576 +96,51 @@ const char *locomotiveSounds[5] = {
"ZFX1007B"
};
-static const SoundManager::FlagType soundFlags[32] = {
- SoundManager::kFlagDefault, SoundManager::kFlag15, SoundManager::kFlag14, SoundManager::kFlag13, SoundManager::kFlag12,
- SoundManager::kFlag11, SoundManager::kFlag11, SoundManager::kFlag10, SoundManager::kFlag10, SoundManager::kFlag9, SoundManager::kFlag9, SoundManager::kFlag8, SoundManager::kFlag8,
- SoundManager::kFlag7, SoundManager::kFlag7, SoundManager::kFlag7, SoundManager::kFlag6, SoundManager::kFlag6, SoundManager::kFlag6,
- SoundManager::kFlag5, SoundManager::kFlag5, SoundManager::kFlag5, SoundManager::kFlag5, SoundManager::kFlag4, SoundManager::kFlag4, SoundManager::kFlag4, SoundManager::kFlag4,
- SoundManager::kFlag3, SoundManager::kFlag3, SoundManager::kFlag3, SoundManager::kFlag3, SoundManager::kFlag3
+static const SoundFlag soundFlags[32] = {
+ kFlagDefault,
+ kFlag15,
+ kFlag14,
+ kFlag13,
+ kFlag12,
+ kFlag11, kFlag11,
+ kFlag10, kFlag10,
+ kFlag9, kFlag9,
+ kFlag8, kFlag8,
+ kFlag7, kFlag7, kFlag7,
+ kFlag6, kFlag6, kFlag6,
+ kFlag5, kFlag5, kFlag5, kFlag5,
+ kFlag4, kFlag4, kFlag4, kFlag4,
+ kFlag3, kFlag3, kFlag3, kFlag3, kFlag3
};
-SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine), _state(0), _currentType(kSoundType16), _flag(0) {
+SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine) {
+ _loopingSoundDuration = 0;
+
+ _queue = new SoundQueue(engine);
+
+ memset(&_lastWarning, 0, sizeof(_lastWarning));
+
// Initialize unknown data
_data0 = 0;
_data1 = 0;
_data2 = 0;
-
- memset(&_buffer, 0, sizeof(_buffer));
- memset(&_lastWarning, 0, sizeof(_lastWarning));
-
- // Sound cache
- _soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE);
-
- _drawSubtitles = 0;
- _currentSubtitle = NULL;
}
SoundManager::~SoundManager() {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- SAFE_DELETE(*i);
- _soundList.clear();
-
- // Entries in the cache are just pointers to sound list entries
- _soundCache.clear();
-
- for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i)
- SAFE_DELETE(*i);
- _subtitles.clear();
-
- _currentSubtitle = NULL;
-
- free(_soundCacheData);
+ SAFE_DELETE(_queue);
// Zero passed pointers
_engine = NULL;
}
//////////////////////////////////////////////////////////////////////////
-// Timer
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::handleTimer() {
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- SoundEntry *entry = (*i);
- if (entry->stream == NULL) {
- SAFE_DELETE(*i);
- i = _soundList.reverse_erase(i);
- continue;
- } else if (!entry->soundStream) {
- entry->soundStream = new StreamedSound();
-
- // TODO: stream any sound in the queue after filtering
- entry->soundStream->load(entry->stream);
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound queue management
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::updateQueue() {
- // TODO add mutex lock!
- warning("Sound::updateQueue: not implemented!");
-}
-
-void SoundManager::resetQueue(SoundType type1, SoundType type2) {
- if (!type2)
- type2 = type1;
-
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->type != type1 && (*i)->type != type2)
- resetEntry(*i);
- }
-}
-
-void SoundManager::removeFromQueue(EntityIndex entity) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(entity);
- if (entry)
- resetEntry(entry);
-}
-
-void SoundManager::removeFromQueue(Common::String filename) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(filename);
- if (entry)
- resetEntry(entry);
-}
-
-void SoundManager::clearQueue() {
- _flag |= 4;
-
- // FIXME: Wait a while for a flag to be set
- //for (int i = 0; i < 3000000; i++)
- // if (_flag & 8)
- // break;
-
- _flag |= 8;
-
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- SoundEntry *entry = (*i);
-
- // Delete entry
- removeEntry(entry);
- SAFE_DELETE(entry);
-
- i = _soundList.reverse_erase(i);
- }
-
- updateSubtitles();
-}
-
-bool SoundManager::isBuffered(EntityIndex entity) {
- Common::StackLock locker(_mutex);
-
- return (getEntry(entity) != NULL);
-}
-
-bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(filename);
-
- if (testForEntity)
- return entry != NULL && !entry->entity;
-
- return (entry != NULL);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Entry
+// Sound-related functions
//////////////////////////////////////////////////////////////////////////
-void SoundManager::setupEntry(SoundEntry *entry, Common::String name, FlagType flag, int a4) {
- if (!entry)
- error("SoundManager::setupEntry: Invalid entry!");
-
- entry->field_4C = a4;
- setEntryType(entry, flag);
- setEntryStatus(entry, flag);
-
- // Add entry to sound list
- _soundList.push_back(entry);
-
- // TODO Add entry to cache and load sound data
- //setupCache(entry);
- loadSoundData(entry, name);
-}
-
-void SoundManager::setEntryType(SoundEntry *entry, FlagType flag) {
- switch (flag & kFlagType9) {
- default:
- case kFlagNone:
- entry->type = _currentType;
- _currentType = (SoundType)(_currentType + 1);
- break;
+void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) {
+ if (_queue->isBuffered(entity) && entity)
+ _queue->removeFromQueue(entity);
- case kFlagType1_2: {
- SoundEntry *previous2 = getEntry(kSoundType2);
- if (previous2)
- updateEntry(previous2, 0);
-
- SoundEntry *previous = getEntry(kSoundType1);
- if (previous) {
- previous->type = kSoundType2;
- updateEntry(previous, 0);
- }
-
- entry->type = kSoundType1;
- }
- break;
-
- case kFlagType3: {
- SoundEntry *previous = getEntry(kSoundType3);
- if (previous) {
- previous->type = kSoundType4;
- updateEntry(previous, 0);
- }
-
- entry->type = kSoundType11;
- }
- break;
-
- case kFlagType7: {
- SoundEntry *previous = getEntry(kSoundType7);
- if (previous)
- previous->type = kSoundType8;
-
- entry->type = kSoundType7;
- }
- break;
-
- case kFlagType9: {
- SoundEntry *previous = getEntry(kSoundType9);
- if (previous)
- previous->type = kSoundType10;
-
- entry->type = kSoundType9;
- }
- break;
-
- case kFlagType11: {
- SoundEntry *previous = getEntry(kSoundType11);
- if (previous)
- previous->type = kSoundType14;
-
- entry->type = kSoundType11;
- }
- break;
-
- case kFlagType13: {
- SoundEntry *previous = getEntry(kSoundType13);
- if (previous)
- previous->type = kSoundType14;
-
- entry->type = kSoundType13;
- }
- break;
- }
-}
-
-void SoundManager::setEntryStatus(SoundEntry *entry, FlagType flag) const {
- SoundStatus status = (SoundStatus)flag;
- if (!((status & 0xFF) & kSoundStatusClear1))
- status = (SoundStatus)(status | kSoundStatusClear2);
-
- if (((status & 0xFF00) >> 8) & kSoundStatusClear0)
- entry->status.status = (uint32)status;
- else
- entry->status.status = (status | kSoundStatusClear4);
-}
-
-void SoundManager::setInCache(SoundEntry *entry) {
- entry->status.status |= kSoundStatusClear2;
-}
-
-bool SoundManager::setupCache(SoundEntry *entry) {
- if (entry->soundData)
- return true;
-
- if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) {
-
- SoundEntry *cacheEntry = NULL;
- uint32 size = 1000;
-
- for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
- if (!((*i)->status.status & kSoundStatus_180)) {
- uint32 newSize = (*i)->field_4C + ((*i)->status.status & kSoundStatusClear1);
-
- if (newSize < size) {
- cacheEntry = (*i);
- size = newSize;
- }
- }
- }
-
- if (entry->field_4C <= size)
- return false;
-
- if (cacheEntry)
- setInCache(cacheEntry);
-
- // TODO: Wait until the cache entry is ready to be removed
- while (!(cacheEntry->status.status1 & 1))
- ;
-
- if (cacheEntry->soundData)
- removeFromCache(cacheEntry);
-
- _soundCache.push_back(entry);
- entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
- } else {
- _soundCache.push_back(entry);
- entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
- }
-
- return true;
-}
-
-void SoundManager::removeFromCache(SoundEntry *entry) {
- for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
- if ((*i) == entry) {
- // Remove sound buffer
- entry->soundData = NULL;
-
- // Remove entry from sound cache
- i = _soundCache.reverse_erase(i);
- }
- }
-}
-
-void SoundManager::clearStatus() {
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- (*i)->status.status |= kSoundStatusClear3;
-}
-
-void SoundManager::loadSoundData(SoundEntry *entry, Common::String name) {
- entry->name2 = name;
-
- // Load sound data
- entry->stream = getArchive(name);
-
- if (!entry->stream)
- entry->stream = getArchive("DEFAULT.SND");
-
- if (entry->stream) {
- warning("Sound::loadSoundData: not implemented!");
- } else {
- entry->status.status = kSoundStatusRemoved;
- }
-}
-
-void SoundManager::resetEntry(SoundEntry *entry) const {
- entry->status.status |= kSoundStatusRemoved;
- entry->entity = kEntityPlayer;
-
- if (entry->stream) {
- if (!entry->soundStream) {
- SAFE_DELETE(entry->stream);
- } else {
- entry->soundStream->stop();
- SAFE_DELETE(entry->soundStream);
- }
-
- entry->stream = NULL;
- }
-}
-
-
-void SoundManager::removeEntry(SoundEntry *entry) {
- entry->status.status |= kSoundStatusRemoved;
-
- // Loop until ready
- while (!(entry->status.status1 & 4) && !(_flag & 8) && (_flag & 1))
- ; // empty loop body
-
- // The original game remove the entry from the cache here,
- // but since we are called from within an iterator loop
- // we will remove the entry there
- // removeFromCache(entry);
-
- if (entry->subtitle) {
- drawSubtitle(entry->subtitle);
- SAFE_DELETE(entry->subtitle);
- }
-
- if (entry->entity) {
- if (entry->entity == kEntitySteam)
- playLoopingSound();
- else if (entry->entity != kEntityTrain)
- getSavePoints()->push(kEntityPlayer, entry->entity, kActionEndSound);
- }
-}
-
-void SoundManager::updateEntry(SoundEntry *entry, uint value) const {
- if (!(entry->status.status3 & 64)) {
- int value2 = value;
-
- entry->status.status |= kSoundStatus_100000;
-
- if (value) {
- if (_flag & 32) {
- entry->field_40 = value;
- value2 = value * 2 + 1;
- }
-
- entry->field_3C = value2;
- } else {
- entry->field_3C = 0;
- entry->status.status |= kSoundStatus_40000000;
- }
- }
-}
-
-void SoundManager::updateEntryState(SoundEntry *entry) const {
- if (_flag & 32) {
- if (entry->type != kSoundType9 && entry->type != kSoundType7 && entry->type != kSoundType5) {
- uint32 status = entry->status.status & kSoundStatusClear1;
-
- entry->status.status &= kSoundStatusClearAll;
-
- entry->field_40 = status;
- entry->status.status |= status * 2 + 1;
- }
- }
-
- entry->status.status |= kSoundStatus_20;
-}
-
-void SoundManager::processEntry(EntityIndex entity) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(entity);
- if (entry) {
- updateEntry(entry, 0);
- entry->entity = kEntityPlayer;
- }
-}
-
-void SoundManager::processEntry(SoundType type) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(type);
- if (entry)
- updateEntry(entry, 0);
-}
-
-void SoundManager::setupEntry(SoundType type, EntityIndex index) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(type);
- if (entry)
- entry->entity = index;
-}
-
-void SoundManager::processEntry(Common::String filename) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(filename);
- if (entry) {
- updateEntry(entry, 0);
- entry->entity = kEntityPlayer;
- }
-}
-
-void SoundManager::processEntries() {
- _state = 0;
-
- processEntry(kSoundType1);
- processEntry(kSoundType2);
-}
-
-uint32 SoundManager::getEntryTime(EntityIndex index) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(index);
- if (entry)
- return entry->time;
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Misc
-//////////////////////////////////////////////////////////////////////////
-
-void SoundManager::unknownFunction4() {
- // TODO: Add mutex ?
- warning("Sound::unknownFunction4: not implemented!");
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Entry search
-//////////////////////////////////////////////////////////////////////////
-SoundManager::SoundEntry *SoundManager::getEntry(EntityIndex index) {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->entity == index)
- return *i;
- }
-
- return NULL;
-}
-
-SoundManager::SoundEntry *SoundManager::getEntry(Common::String name) {
- if (!name.contains('.'))
- name += ".SND";
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->name2 == name)
- return *i;
- }
-
- return NULL;
-}
-
-SoundManager::SoundEntry *SoundManager::getEntry(SoundType type) {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->type == type)
- return *i;
- }
-
- return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Savegame
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
- s.syncAsUint32LE(_state);
- s.syncAsUint32LE(_currentType);
-
- // Compute the number of entries to save
- uint32 numEntries = count();
- s.syncAsUint32LE(numEntries);
-
- Common::StackLock locker(_mutex);
-
- // Save or load each entry data
- if (s.isSaving()) {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- SoundEntry *entry = *i;
- if (entry->name2.matchString("NISSND?") && (entry->status.status & kFlagType7) != kFlag3) {
- s.syncAsUint32LE(entry->status.status); // status;
- s.syncAsUint32LE(entry->type); // type;
- s.syncAsUint32LE(entry->field_1C); // field_8;
- s.syncAsUint32LE(entry->time); // time;
- s.syncAsUint32LE(entry->field_34); // field_10;
- s.syncAsUint32LE(entry->field_38); // field_14;
- s.syncAsUint32LE(entry->entity); // entity;
-
- uint32 field_1C = (uint32)entry->field_48 - _data2;
- if (field_1C > kFlag8)
- field_1C = 0;
- s.syncAsUint32LE(field_1C); // field_1C;
-
- s.syncAsUint32LE(entry->field_4C); // field_20;
-
- char name1[16];
- strcpy((char *)&name1, entry->name1.c_str());
- s.syncBytes((byte *)&name1, 16);
-
- char name2[16];
- strcpy((char *)&name2, entry->name2.c_str());
- s.syncBytes((byte *)&name2, 16);
- }
- }
- } else {
- warning("Sound::saveLoadWithSerializer: not implemented!");
- s.skip(numEntries * 64);
- }
-}
-
-
-// FIXME: We probably need another mutex here to protect during the whole savegame process
-// as we could have removed an entry between the time we check the count and the time we
-// save the entries
-uint32 SoundManager::count() {
- Common::StackLock locker(_mutex);
-
- uint32 numEntries = 0;
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- if ((*i)->name2.matchString("NISSND?"))
- ++numEntries;
-
- return numEntries;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Game-related functions
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playSound(EntityIndex entity, Common::String filename, FlagType flag, byte a4) {
- if (isBuffered(entity) && entity)
- removeFromQueue(entity);
-
- FlagType currentFlag = (flag == -1) ? getSoundFlag(entity) : (FlagType)(flag | 0x80000);
+ SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000);
// Add .SND at the end of the filename if needed
if (!filename.contains('.'))
@@ -675,27 +151,25 @@ void SoundManager::playSound(EntityIndex entity, Common::String filename, FlagTy
getSavePoints()->push(kEntityPlayer, entity, kActionEndSound);
}
-bool SoundManager::playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4) {
- SoundEntry *entry = new SoundEntry();
+bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4) {
+ SoundEntry *entry = new SoundEntry(_engine);
- Common::StackLock locker(_mutex);
-
- setupEntry(entry, filename, flag, 30);
- entry->entity = entity;
+ entry->open(filename, flag, 30);
+ entry->setEntity(entity);
if (a4) {
- entry->field_48 = _data2 + 2 * a4;
- entry->status.status |= kSoundStatus_8000;
+ entry->setField48(_data2 + 2 * a4);
+ entry->setStatus(entry->getStatus().status | kSoundStatus_8000);
} else {
// Get subtitles name
while (filename.size() > 4)
filename.deleteLastChar();
- showSubtitle(entry, filename);
- updateEntryState(entry);
+ entry->showSubtitle(filename);
+ entry->updateState();
}
- return (entry->type != kSoundTypeNone);
+ return (entry->getType() != kSoundTypeNone);
}
void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
@@ -708,7 +182,7 @@ void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
return;
int _action = (int)action;
- FlagType flag = getSoundFlag(entity);
+ SoundFlag flag = getSoundFlag(entity);
switch (action) {
case 36: {
@@ -826,17 +300,17 @@ void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
void SoundManager::playSteam(CityIndex index) {
if (index >= ARRAYSIZE(cities))
- error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
+ error("[SoundManager::playSteam] Invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
- _state |= kSoundState2;
+ _queue->resetState(kSoundState2);
- if (!getEntry(kSoundType1))
+ if (!_queue->getEntry(kSoundType1))
playSoundWithSubtitles("STEAM.SND", kFlagSteam, kEntitySteam);
// Get the new sound entry and show subtitles
- SoundEntry *entry = getEntry(kSoundType1);
+ SoundEntry *entry = _queue->getEntry(kSoundType1);
if (entry)
- showSubtitle(entry, cities[index]);
+ entry->showSubtitle(cities[index]);
}
void SoundManager::playFightSound(byte action, byte a4) {
@@ -883,15 +357,15 @@ void SoundManager::playFightSound(byte action, byte a4) {
playSound(kEntityTrain, Common::String::format("LIB%03d.SND", _action), kFlagDefault, a4);
}
-void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, FlagType flag, byte a4) {
- if (isBuffered(getDialogName(entityDialog)))
- removeFromQueue(getDialogName(entityDialog));
+void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4) {
+ if (_queue->isBuffered(getDialogName(entityDialog)))
+ _queue->removeFromQueue(getDialogName(entityDialog));
playSound(entity, getDialogName(entityDialog), flag, a4);
}
void SoundManager::playLocomotiveSound() {
- playSound(kEntityPlayer, locomotiveSounds[rnd(5)], (FlagType)(rnd(15) + 2));
+ playSound(kEntityPlayer, locomotiveSounds[rnd(5)], (SoundFlag)(rnd(15) + 2));
}
const char *SoundManager::getDialogName(EntityIndex entity) const {
@@ -1198,19 +672,19 @@ const char *SoundManager::getDialogName(EntityIndex entity) const {
// Letters & Messages
//////////////////////////////////////////////////////////////////////////
void SoundManager::readText(int id){
- if (!isBuffered(kEntityTables4))
+ if (!_queue->isBuffered(kEntityTables4))
return;
if (id < 0 || (id > 8 && id < 50) || id > 64)
- error("Sound::readText - attempting to use invalid id. Valid values [1;8] - [50;64], was %d", id);
+ error("[Sound::readText] Attempting to use invalid id. Valid values [1;8] - [50;64], was %d", id);
// Get proper message file (names are stored in sequence in the array but id is [1;8] - [50;64])
const char *text = messages[id <= 8 ? id : id - 41];
// Check if file is in cache for id [1;8]
if (id <= 8)
- if (isBuffered(text))
- removeFromQueue(text);
+ if (_queue->isBuffered(text))
+ _queue->removeFromQueue(text);
playSound(kEntityTables4, text, kFlagDefault);
}
@@ -1397,8 +871,8 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar
_lastWarning[compartment - 28] = getState()->timeTicks;
}
-void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, FlagType flag) {
- if (isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain)
+void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag flag) {
+ if (_queue->isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain)
return;
if (entity2 == kEntityFrancois || entity2 == kEntityMax)
@@ -1747,7 +1221,7 @@ const char *SoundManager::justAMinuteCath() const {
//////////////////////////////////////////////////////////////////////////
// Sound flags
//////////////////////////////////////////////////////////////////////////
-SoundManager::FlagType SoundManager::getSoundFlag(EntityIndex entity) const {
+SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
if (entity == kEntityPlayer)
return kFlagDefault;
@@ -1755,7 +1229,7 @@ SoundManager::FlagType SoundManager::getSoundFlag(EntityIndex entity) const {
return kFlagNone;
// Compute sound value
- FlagType ret = kFlag2;
+ SoundFlag ret = kFlag2;
// Get default value if valid
int index = ABS(getEntityData(entity)->entityPosition - getEntityData(kEntityPlayer)->entityPosition) / 230;
@@ -1768,7 +1242,7 @@ SoundManager::FlagType SoundManager::getSoundFlag(EntityIndex entity) const {
&& !getEntities()->isOutsideAnnaWindow())
return kFlagNone;
- return (FlagType)(ret / 6);
+ return (SoundFlag)(ret / 6);
}
switch (getEntityData(entity)->car) {
@@ -1777,25 +1251,25 @@ SoundManager::FlagType SoundManager::getSoundFlag(EntityIndex entity) const {
case kCarKronos:
if (getEntities()->isInKronosSalon(entity) != getEntities()->isInKronosSalon(kEntityPlayer))
- ret = (FlagType)(ret * 2);
+ ret = (SoundFlag)(ret * 2);
break;
case kCarGreenSleeping:
case kCarRedSleeping:
if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInKronosSalon(entity))
- ret = (FlagType)(ret * 2);
+ ret = (SoundFlag)(ret * 2);
if (getEntityData(kEntityPlayer)->location
&& (getEntityData(entity)->entityPosition != kPosition_1 || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
- ret = (FlagType)(ret * 2);
+ ret = (SoundFlag)(ret * 2);
break;
case kCarRestaurant:
if (getEntities()->isInSalon(entity) == getEntities()->isInSalon(kEntityPlayer)
&& (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer)))
- ret = (FlagType)(ret * 2);
+ ret = (SoundFlag)(ret * 2);
else
- ret = (FlagType)(ret * 4);
+ ret = (SoundFlag)(ret * 4);
break;
}
@@ -1803,149 +1277,103 @@ SoundManager::FlagType SoundManager::getSoundFlag(EntityIndex entity) const {
}
//////////////////////////////////////////////////////////////////////////
-// Subtitles
+// Misc
//////////////////////////////////////////////////////////////////////////
-void SoundManager::updateSubtitles() {
- Common::StackLock locker(_mutex);
-
- uint32 index = 0;
- SubtitleEntry *subtitle = NULL;
-
- for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
- uint32 current_index = 0;
- SoundEntry *soundEntry = (*i)->sound;
- SoundStatus status = (SoundStatus)soundEntry->status.status;
-
- if (!(status & kSoundStatus_40)
- || status & 0x180
- || soundEntry->time == 0
- || (status & 0x1F) < 6
- || ((getFlags()->nis & 0x8000) && soundEntry->field_4C < 90)) {
- current_index = 0;
- } else {
- current_index = soundEntry->field_4C + (status & 0x1F);
-
- if (_currentSubtitle == (*i))
- current_index += 4;
- }
+void SoundManager::playLoopingSound(int param) {
+ SoundEntry *entry = _queue->getEntry(kSoundType1);
- if (index < current_index) {
- index = current_index;
- subtitle = (*i);
- }
- }
-
- if (_currentSubtitle == subtitle) {
- if (subtitle)
- setupSubtitleAndDraw(subtitle);
-
- return;
- }
+ static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500,
+ kPosition_6470, kPosition_5790,
+ kPosition_4840, kPosition_4070,
+ kPosition_3050, kPosition_2740 };
- if (_drawSubtitles & 1)
- drawSubtitleOnScreen(subtitle);
-
- if (subtitle) {
- loadSubtitleData(subtitle);
- setupSubtitleAndDraw(subtitle);
- }
-}
-
-void SoundManager::showSubtitle(SoundEntry *entry, Common::String filename) {
- entry->subtitle = loadSubtitle(filename, entry);
-
- if (entry->subtitle->status.status2 & 4) {
- drawSubtitle(entry->subtitle);
- SAFE_DELETE(entry->subtitle);
- } else {
- entry->status.status |= kSoundStatus_20000;
- }
-}
+ byte numLoops[8];
+ numLoops[1] = 4;
+ numLoops[2] = 2;
+ numLoops[3] = 2;
+ numLoops[4] = 2;
+ numLoops[5] = 2;
+ numLoops[6] = 2;
-SoundManager::SubtitleEntry *SoundManager::loadSubtitle(Common::String filename, SoundEntry *soundEntry) {
- SubtitleEntry *entry = new SubtitleEntry();
- _subtitles.push_back(entry);
+ char tmp[80];
+ tmp[0] = 0;
- // Set sound entry and filename
- entry->filename = filename + ".SBE";
- entry->sound = soundEntry;
+ int partNumber = 1;
+ int fnameLen = 6;
- // Load subtitle data
- if (_engine->getResourceManager()->hasFile(filename)) {
- if (_drawSubtitles & 2)
- return entry;
+ if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) {
+ if (_queue->getSoundState() & 2) {
+ strcpy(tmp, "STEAM.SND");
- loadSubtitleData(entry);
- } else {
- entry->status.status = kSoundStatus_400;
- }
-
- return entry;
-}
-
-void SoundManager::loadSubtitleData(SubtitleEntry * entry) {
- entry->data = new SubtitleManager(_engine->getFont());
- entry->data->load(getArchive(entry->filename));
-
- _drawSubtitles |= 2;
- _currentSubtitle = entry;
-}
-
-void SoundManager::setupSubtitleAndDraw(SubtitleEntry *subtitle) {
- if (!subtitle->data) {
- subtitle->data = new SubtitleManager(_engine->getFont());
- subtitle->data->load(getArchive(subtitle->filename));
- }
+ _loopingSoundDuration = 32767;
+ } else {
+ if (getEntityData(kEntityPlayer)->location == kLocationOutsideTrain) {
+ partNumber = 6;
+ } else {
+ if (getEntities()->isInsideCompartments(kEntityPlayer)) {
+ int objNum = (getEntityData(kEntityPlayer)->car - 3) < 1 ? 9 : 40; // Weird numbers
+
+ numLoops[0] = 0;
+
+ for (int pos = 0; pos < 8; pos++) {
+ if (numLoops[0])
+ break;
+ if (getEntities()->isInsideCompartment(kEntityPlayer, getEntityData(kEntityPlayer)->car, positions[pos])) {
+ numLoops[0] = 1;
+ partNumber = (getObjects()->get((ObjectIndex)objNum).location - 2) < 1 ? 6 : 1;
+ }
+ objNum++;
+ }
+ } else {
+ switch (getEntityData(kEntityPlayer)->car) {
+ case 1:
+ case 6:
+ partNumber = 4;
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ partNumber = 1;
+ break;
+ case 7:
+ partNumber = 5;
+ break;
+ case 8:
+ partNumber = 99;
+ break;
+ case 9:
+ partNumber = 3;
+ break;
+ default:
+ partNumber = 6;
+ break;
+ }
+ }
+ }
- if (subtitle->data->getMaxTime() > subtitle->sound->time) {
- subtitle->status.status = kSoundStatus_400;
- } else {
- subtitle->data->setTime((uint16)subtitle->sound->time);
+ if (partNumber != 99)
+ sprintf(tmp, "LOOP%d%c.SND", partNumber, _engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A');
+ }
- if (_drawSubtitles & 1)
- drawSubtitleOnScreen(subtitle);
- }
+ if (getFlags()->flag_3)
+ fnameLen = 5;
- _currentSubtitle = subtitle;
-}
+ if (!entry || scumm_strnicmp(entry->getName2().c_str(), tmp, fnameLen)) {
+ _loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260;
-void SoundManager::drawSubtitle(SubtitleEntry *subtitle) {
- // Remove subtitle from queue
- _subtitles.remove(subtitle);
+ if (partNumber != 99) {
+ playSoundWithSubtitles(tmp, kFlagLoopedSound, kEntitySteam);
- if (subtitle == _currentSubtitle) {
- drawSubtitleOnScreen(subtitle);
+ if (entry)
+ entry->update(0);
- _currentSubtitle = NULL;
- _drawSubtitles = 0;
+ SoundEntry *entry1 = _queue->getEntry(kSoundType1);
+ if (entry1)
+ entry1->update(7);
+ }
+ }
}
}
-void SoundManager::drawSubtitleOnScreen(SubtitleEntry *subtitle) {
- if (!subtitle)
- error("SoundManager::drawSubtitleOnScreen: Invalid subtitle entry!");
-
- _drawSubtitles &= ~1;
-
- if (subtitle->data == NULL)
- return;
-
- if (_drawSubtitles & 1)
- _engine->getGraphicsManager()->draw(subtitle->data, GraphicsManager::kBackgroundOverlay);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Misc
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playLoopingSound() {
- warning("SoundManager::playLoopingSound: not implemented!");
-}
-
-void SoundManager::stopAllSound() {
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- (*i)->soundStream->stop();
-}
-
} // End of namespace LastExpress
diff --git a/engines/lastexpress/sound/sound.h b/engines/lastexpress/sound/sound.h
new file mode 100644
index 0000000000..797e52646e
--- /dev/null
+++ b/engines/lastexpress/sound/sound.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 LASTEXPRESS_SOUND_H
+#define LASTEXPRESS_SOUND_H
+
+#include "lastexpress/shared.h"
+
+#include "common/str.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SoundQueue;
+
+class SoundManager {
+public:
+ SoundManager(LastExpressEngine *engine);
+ ~SoundManager();
+
+ // Sound playing
+ void playSound(EntityIndex entity, Common::String filename, SoundFlag flag = kFlagInvalid, byte a4 = 0);
+ bool playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4 = 0);
+ void playSoundEvent(EntityIndex entity, byte action, byte a3 = 0);
+ void playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4);
+ void playSteam(CityIndex index);
+ void playFightSound(byte action, byte a4);
+ void playLocomotiveSound();
+ void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
+ void playLoopingSound(int param);
+
+ // Dialog & Letters
+ void readText(int id);
+ const char *getDialogName(EntityIndex entity) const;
+
+ // Sound bites
+ void excuseMe(EntityIndex entity, EntityIndex entity2 = kEntityPlayer, SoundFlag flag = kFlagNone);
+ void excuseMeCath();
+ const char *justCheckingCath() const;
+ const char *wrongDoorCath() const;
+ const char *justAMinuteCath() const;
+
+ // Flags
+ SoundFlag getSoundFlag(EntityIndex index) const;
+
+ // Accessors
+ SoundQueue *getQueue() { return _queue; }
+ uint32 getData2() { return _data2; }
+
+private:
+ LastExpressEngine *_engine;
+ SoundQueue *_queue;
+
+ // Compartment warnings by Mertens or Coudert
+ uint32 _lastWarning[12];
+
+ // Looping sound
+ int _loopingSoundDuration;
+
+ // Unknown data
+ uint32 _data0;
+ uint32 _data1;
+ uint32 _data2;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SOUND_H
diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp
index 68410875f7..ef4a22f73a 100644
--- a/engines/lure/debugger.cpp
+++ b/engines/lure/debugger.cpp
@@ -549,14 +549,19 @@ bool Debugger::cmd_showAnim(int argc, const char **argv) {
}
bool Debugger::cmd_saveStrings(int argc, const char **argv) {
- StringData &strings = StringData::getReference();
- char buffer[32768];
-
if (argc != 2) {
DebugPrintf("strings <stringId>\n");
return true;
}
+ StringData &strings = StringData::getReference();
+
+ char *buffer = (char *)malloc(32768);
+ if (!buffer) {
+ DebugPrintf("Cannot allocate strings buffer\n");
+ return true;
+ }
+
uint16 id = strToInt(argv[1]);
strings.getString(id, buffer, NULL, NULL);
DebugPrintf("%s\n", buffer);
@@ -577,6 +582,9 @@ bool Debugger::cmd_saveStrings(int argc, const char **argv) {
DebugPrintf("Done\n");
*/
+
+ free(buffer);
+
return true;
}
diff --git a/engines/lure/detection.cpp b/engines/lure/detection.cpp
index ced0be0cfb..081625863d 100644
--- a/engines/lure/detection.cpp
+++ b/engines/lure/detection.cpp
@@ -175,34 +175,17 @@ static const LureGameDescription gameDescriptions[] = {
} // End of namespace Lure
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Lure::gameDescriptions,
- // Size of that superset structure
- sizeof(Lure::LureGameDescription),
- // Number of bytes to compute MD5 sum for
- 1024,
- // List of all engine targets
- lureGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "lure",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- kADFlagUseExtraAsHint,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class LureMetaEngine : public AdvancedMetaEngine {
public:
- LureMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ LureMetaEngine() : AdvancedMetaEngine(Lure::gameDescriptions, sizeof(Lure::LureGameDescription), lureGames) {
+ _md5Bytes = 1024;
+ _singleid = "lure";
+
+ // Use kADFlagUseExtraAsHint to distinguish between EGA and VGA versions
+ // of italian Lure when their datafiles sit in the same directory.
+ _flags = kADFlagUseExtraAsHint;
+ _guioptions = Common::GUIO_NOSPEECH;
+ }
virtual const char *getName() const {
return "Lure";
diff --git a/engines/lure/memory.cpp b/engines/lure/memory.cpp
index c5c28fa8bc..137a8f6bee 100644
--- a/engines/lure/memory.cpp
+++ b/engines/lure/memory.cpp
@@ -93,8 +93,12 @@ void MemoryBlock::copyFrom(const byte *src, uint32 srcPos, uint32 destPos, uint3
void MemoryBlock::reallocate(uint32 size1) {
_size = size1;
- _data = (byte *) realloc(_data, size1);
- if (!_data) error ("Failed reallocating memory block");
+
+ byte *tmp = (byte *) realloc(_data, size1);
+ if (!tmp)
+ error ("[MemoryBlock::reallocate] Failed reallocating memory block");
+
+ _data = tmp;
}
} // End of namespace Lure
diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h
index 49b6ef78ba..8d6c557297 100644
--- a/engines/lure/res_struct.h
+++ b/engines/lure/res_struct.h
@@ -470,7 +470,7 @@ public:
bool isEmpty() const { return _actions.begin() == _actions.end(); }
void clear() { _actions.clear(); }
CurrentActionEntry &top() { return **_actions.begin(); }
- CurrentActionEntry &bottom() {
+ CurrentActionEntry &bottom() {
ActionsList::iterator i = _actions.end();
--i;
return **i;
diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp
index 39a3f175cd..4f315dd396 100644
--- a/engines/m4/animation.cpp
+++ b/engines/m4/animation.cpp
@@ -91,7 +91,7 @@ void MadsAnimation::initialize(const Common::String &filename, uint16 flags, M4S
_scrollY = animStream->readSint16LE();
_scrollTicks = animStream->readUint16LE();
animStream->skip(8);
-
+
animStream->read(buffer, FILENAME_SIZE);
buffer[FILENAME_SIZE] = '\0';
_interfaceFile = Common::String(buffer);
@@ -230,7 +230,7 @@ void MadsAnimation::initialize(const Common::String &filename, uint16 flags, M4S
// Load all the sprite sets for the animation
for (int i = 0; i < spriteListCount; ++i) {
if (_field12 && (i == _spriteListIndex))
- // Skip over field, since it's manually loaded
+ // Skip over field, since it's manually loaded
continue;
_spriteListIndexes[i] = _view->_spriteSlots.addSprites(_spriteSetNames[i].c_str());
@@ -242,7 +242,7 @@ void MadsAnimation::initialize(const Common::String &filename, uint16 flags, M4S
if (madsRes)
resName += "*";
resName += _spriteSetNames[_spriteListIndex];
-
+
_spriteListIndexes[_spriteListIndex] = _view->_spriteSlots.addSprites(resName.c_str());
}
@@ -298,7 +298,7 @@ void MadsAnimation::update() {
if (_field12) {
int spriteListIndex = _spriteListIndexes[_spriteListIndex];
int newIndex = -1;
-
+
for (uint idx = _oldFrameEntry; idx < _frameEntries.size(); ++idx) {
if (_frameEntries[idx].frameNumber > _currentFrame)
break;
@@ -378,7 +378,7 @@ void MadsAnimation::update() {
if (_frameEntries[_oldFrameEntry].frameNumber > _currentFrame)
break;
else if (_frameEntries[_oldFrameEntry].frameNumber == _currentFrame) {
- // Found the correct frame
+ // Found the correct frame
int spriteSlotIndex = 0;
int index = 0;
@@ -393,14 +393,14 @@ void MadsAnimation::update() {
}
++index;
continue;
- }
-
+ }
+
if (spriteSlotIndex == 0) {
int slotIndex = _view->_spriteSlots.getIndex();
MadsSpriteSlot &slot = _view->_spriteSlots[slotIndex];
slot.copy(_frameEntries[_oldFrameEntry].spriteSlot);
slot.seqIndex = _frameEntries[_oldFrameEntry].seqIndex + 0x80;
-
+
SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(
_view->_spriteSlots[slotIndex].spriteListIndex);
slot.spriteType = spriteSet.isBackground() ? BACKGROUND_SPRITE : FOREGROUND_SPRITE;
@@ -408,7 +408,7 @@ void MadsAnimation::update() {
break;
}
}
-
+
++_oldFrameEntry;
}
diff --git a/engines/m4/assets.cpp b/engines/m4/assets.cpp
index 8ffdeb53e0..d6cc71e133 100644
--- a/engines/m4/assets.cpp
+++ b/engines/m4/assets.cpp
@@ -97,8 +97,8 @@ long *DataAsset::getRow(int index) {
return &_data[_recSize * index];
}
-SpriteAsset::SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
- bool asStream, int flags) :
+SpriteAsset::SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
+ bool asStream, int flags) :
BaseAsset(vm) {
_stream = stream;
_palInterface = NULL;
@@ -285,7 +285,7 @@ void SpriteAsset::loadMadsSpriteAsset(MadsM4Engine *vm, Common::SeekableReadStre
// Load the frame
Common::MemoryReadStream *rs = new Common::MemoryReadStream(destData, frameSizes[curFrame]);
- _frames[curFrame].frame = new M4Sprite(rs, _frames[curFrame].x, _frames[curFrame].y,
+ _frames[curFrame].frame = new M4Sprite(rs, _frames[curFrame].x, _frames[curFrame].y,
_frames[curFrame].w, _frames[curFrame].h, false);
delete rs;
@@ -634,7 +634,7 @@ MadsSpriteSetCharInfo::MadsSpriteSetCharInfo(Common::SeekableReadStream *s) {
_totalFrames = s->readByte();
s->skip(1);
_numEntries = s->readUint16LE();
-
+
for (int i = 0; i < 16; ++i)
_frameList[i] = s->readUint16LE();
for (int i = 0; i < 16; ++i)
diff --git a/engines/m4/assets.h b/engines/m4/assets.h
index 90670dde53..25996a421e 100644
--- a/engines/m4/assets.h
+++ b/engines/m4/assets.h
@@ -115,7 +115,7 @@ public:
class SpriteAsset : public BaseAsset {
public:
- SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
+ SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
bool asStream = false, int flags = 0);
SpriteAsset(MadsM4Engine *vm, const char *name);
~SpriteAsset();
@@ -151,7 +151,7 @@ protected:
Common::Array<uint32> _frameOffsets;
Common::Array<SpriteAssetFrame> _frames;
uint32 _frameStartOffset;
-
+
// MADS sprite set fields
uint8 _mode;
bool _isBackground;
diff --git a/engines/m4/detection.cpp b/engines/m4/detection.cpp
index 1aefe3d02d..9c359c081f 100644
--- a/engines/m4/detection.cpp
+++ b/engines/m4/detection.cpp
@@ -79,7 +79,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Burger,
@@ -95,7 +95,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Burger,
@@ -111,7 +111,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::RU_RUS,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Burger,
@@ -127,7 +127,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
GUIO_NONE
},
GType_Burger,
@@ -143,7 +143,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
GUIO_NONE
},
GType_Burger,
@@ -159,7 +159,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Riddle,
@@ -175,7 +175,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Riddle,
@@ -191,7 +191,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Riddle,
@@ -207,7 +207,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Riddle,
@@ -223,7 +223,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Riddle,
@@ -239,7 +239,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
GUIO_NONE
},
GType_Riddle,
@@ -255,7 +255,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NOSPEECH
},
GType_RexNebular,
@@ -271,7 +271,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
GUIO_NONE
},
GType_RexNebular,
@@ -287,7 +287,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NOSPEECH
},
GType_DragonSphere,
@@ -304,7 +304,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_DragonSphere,
@@ -320,7 +320,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
GUIO_NONE
},
GType_DragonSphere,
@@ -336,7 +336,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NOSPEECH
},
GType_Phantom,
@@ -352,7 +352,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GType_Phantom,
@@ -368,7 +368,7 @@ static const M4GameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
GUIO_NONE
},
GType_Phantom,
@@ -384,34 +384,14 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)M4::gameDescriptions,
- // Size of that superset structure
- sizeof(M4::M4GameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- m4Games,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "m4",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOMIDI,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class M4MetaEngine : public AdvancedMetaEngine {
public:
- M4MetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ M4MetaEngine() : AdvancedMetaEngine(M4::gameDescriptions, sizeof(M4::M4GameDescription), m4Games) {
+ _singleid = "m4";
+ _guioptions = Common::GUIO_NOMIDI;
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "MADS/M4";
diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp
index afe2692753..2b2c479673 100644
--- a/engines/m4/dialogs.cpp
+++ b/engines/m4/dialogs.cpp
@@ -265,7 +265,7 @@ void Dialog::setupInputArea() {
*/
bool Dialog::matchCommand(const char *s1, const char *s2) {
bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0;
- _commandCase = isupper(*s1);
+ _commandCase = isupper(static_cast<unsigned char>(*s1));
return result;
}
@@ -532,7 +532,7 @@ void Dialog::display(MadsM4Engine *vm, int widthChars, const char **descEntries)
}
dlg->_lines[0].underline = true;
-
+
dlg->draw();
vm->_viewManager->addView(dlg);
vm->_viewManager->moveToFront(dlg);
@@ -554,7 +554,7 @@ void Dialog::getValue(MadsM4Engine *vm, const char *title, const char *text, int
vm->_viewManager->moveToFront(dlg);
// TODO: How to wait until the dialog is closed
-
+
}
} // End of namespace M4
diff --git a/engines/m4/events.cpp b/engines/m4/events.cpp
index f8225fba3e..b476d08c9c 100644
--- a/engines/m4/events.cpp
+++ b/engines/m4/events.cpp
@@ -253,7 +253,7 @@ bool Mouse::setCursorNum(int cursorIndex) {
_cursor = _cursorSprites->getFrame(cursorIndex);
// Set the cursor to the sprite
- CursorMan.replaceCursor((const byte *)_cursor->getBasePtr(), _cursor->width(), _cursor->height(),
+ CursorMan.replaceCursor((const byte *)_cursor->getBasePtr(), _cursor->width(), _cursor->height(),
_cursor->xOffset, _cursor->yOffset, TRANSPARENT_COLOR_INDEX);
return true;
diff --git a/engines/m4/font.h b/engines/m4/font.h
index b00a393811..5a9c73e5d5 100644
--- a/engines/m4/font.h
+++ b/engines/m4/font.h
@@ -108,7 +108,7 @@ public:
Font *getFont(const char *filename);
void setFont(const char *filename);
- Font *current() {
+ Font *current() {
assert(_currentFont);
return _currentFont;
}
diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp
index bf2c3abe1c..f4aab8ae8f 100644
--- a/engines/m4/globals.cpp
+++ b/engines/m4/globals.cpp
@@ -414,7 +414,7 @@ const char *MadsGlobals::loadMessage(uint index) {
}
/**
- * Adds the specified scene number to list of scenes previously visited
+ * Adds the specified scene number to list of scenes previously visited
*/
void MadsGlobals::addVisitedScene(int newSceneNumber) {
if (!isSceneVisited(newSceneNumber))
@@ -539,7 +539,7 @@ void MadsObject::load(Common::SeekableReadStream *stream) {
}
void MadsObject::setRoom(int roomNumber) {
-
+
}
} // End of namespace M4
diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp
index 786c975850..4c272de32c 100644
--- a/engines/m4/graphics.cpp
+++ b/engines/m4/graphics.cpp
@@ -408,7 +408,7 @@ void M4Surface::copyFrom(M4Surface *src, const Common::Rect &srcBounds, int dest
* Copies a given image onto a destination surface with scaling, transferring only pixels that meet
* the specified depth requirement on a secondary surface contain depth information
*/
-void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth,
+void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth,
M4Surface *depthsSurface, int scale, int transparentColor) {
if (scale == 100) {
@@ -451,7 +451,7 @@ void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth,
}
src->freeData();
- depthsSurface->freeData();
+ depthsSurface->freeData();
return;
}
@@ -501,7 +501,7 @@ void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth,
widthAmount -= destRight;
if (widthAmount > 0)
spriteWidth -= widthAmount;
-
+
int spriteRight = spriteLeft + spriteWidth;
if (spriteWidth <= 0)
return;
@@ -568,7 +568,7 @@ void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth,
}
src->freeData();
- depthsSurface->freeData();
+ depthsSurface->freeData();
this->freeData();
}
@@ -919,7 +919,7 @@ void M4Surface::scrollY(int yAmount) {
// Vertically shift all the lines
Common::copy(pixelsP + (pitch * ySize), pixelsP + (pitch * height()), pixelsP);
// Transfer the buffered lines to the bottom of the screen
- Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (height() - ySize)));
+ Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (height() - ySize)));
}
::free(tempData);
@@ -945,7 +945,7 @@ void M4Surface::translate(RGBList *list, bool isTransparent) {
M4Surface *M4Surface::flipHorizontal() const {
M4Surface *dest = new M4Surface(width(), height());
dest->_rgbList = (this->_rgbList == NULL) ? NULL : this->_rgbList->clone();
-
+
byte *destP = dest->getBasePtr();
for (int y = 0; y < height(); ++y) {
diff --git a/engines/m4/graphics.h b/engines/m4/graphics.h
index 242857ba1a..f3dde454f3 100644
--- a/engines/m4/graphics.h
+++ b/engines/m4/graphics.h
@@ -170,7 +170,7 @@ public:
void frameRect(const Common::Rect &r, uint8 color);
void fillRect(const Common::Rect &r, uint8 color);
void copyFrom(M4Surface *src, const Common::Rect &srcBounds, int destX, int destY, int transparentColor = -1);
- void copyFrom(M4Surface *src, int destX, int destY, int depth, M4Surface *depthSurface,
+ void copyFrom(M4Surface *src, int destX, int destY, int depth, M4Surface *depthSurface,
int scale, int transparentColor = -1);
void update() {
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
index 93f5ab4cba..efc7943114 100644
--- a/engines/m4/m4.cpp
+++ b/engines/m4/m4.cpp
@@ -259,7 +259,7 @@ void MadsM4Engine::dumpFile(const char *filename, bool uncompress) {
Common::DumpFile f;
byte buffer[DUMP_BUFFER_SIZE];
Common::SeekableReadStream *fileS = res()->get(filename);
-
+
if (!f.open(filename))
error("Could not open '%s' for writing", filename);
diff --git a/engines/m4/m4.h b/engines/m4/m4.h
index 18c3936db8..46107cb20a 100644
--- a/engines/m4/m4.h
+++ b/engines/m4/m4.h
@@ -94,7 +94,7 @@ class Animation;
enum M4GameType {
GType_Riddle = 1,
GType_Burger = 2,
- GType_RexNebular = 3,
+ GType_RexNebular = 3,
GType_DragonSphere = 4,
GType_Phantom = 5
};
diff --git a/engines/m4/m4_menus.cpp b/engines/m4/m4_menus.cpp
index 787d8666f6..3384a82c8b 100644
--- a/engines/m4/m4_menus.cpp
+++ b/engines/m4/m4_menus.cpp
@@ -22,6 +22,7 @@
#include "common/algorithm.h" // for find()
#include "common/textconsole.h"
+#include "common/translation.h"
#include "gui/dialog.h"
#include "gui/message.h"
@@ -134,7 +135,7 @@ void OrionCallbacks::saveLoadSaveFn(DialogView *view, MenuObject *item) {
bool succeeded = view->vm()->_saveLoad->save(view->_selectedSlot + 1, textItem->getText());
if (!succeeded) {
- GUI::MessageDialog dialog("Save game failed!");
+ GUI::MessageDialog dialog(_("Save game failed!"));
dialog.runModal();
}
diff --git a/engines/m4/m4_views.cpp b/engines/m4/m4_views.cpp
index 4eb84a7488..78c409252b 100644
--- a/engines/m4/m4_views.cpp
+++ b/engines/m4/m4_views.cpp
@@ -217,7 +217,7 @@ const char *INTERFACE_SERIES = "999intr";
#define SPR(x) _sprites->getFrame(x)
-M4InterfaceView::M4InterfaceView(MadsM4Engine *vm):
+M4InterfaceView::M4InterfaceView(MadsM4Engine *vm):
GameInterfaceView(vm, Common::Rect(0, vm->_screen->height() - INTERFACE_HEIGHT,
vm->_screen->width(), vm->_screen->height())),
_statusText(GUITextField(this, Common::Rect(200, 1, 450, 21))),
diff --git a/engines/m4/mads_anim.cpp b/engines/m4/mads_anim.cpp
index d35b31943a..2ea576dfa4 100644
--- a/engines/m4/mads_anim.cpp
+++ b/engines/m4/mads_anim.cpp
@@ -536,7 +536,7 @@ void AnimviewView::updateState() {
// Clear up current background and sprites
_backgroundSurface.reset();
clearLists();
-
+
// Reset flags
_startFrame = -1;
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp
index b1e57bd7f3..cc28a26e68 100644
--- a/engines/m4/mads_logic.cpp
+++ b/engines/m4/mads_logic.cpp
@@ -177,7 +177,7 @@ void MadsSceneLogic::initializeDataMap() {
uint32 MadsSceneLogic::getDataValue(int dataId) {
switch (dataId) {
- case 1:
+ case 1:
return _madsVm->scene()->_abortTimersMode2;
case 2:
return _madsVm->scene()->_abortTimers;
@@ -208,7 +208,7 @@ uint32 MadsSceneLogic::getDataValue(int dataId) {
void MadsSceneLogic::setDataValue(int dataId, uint16 dataValue) {
switch (dataId) {
- case 1:
+ case 1:
_madsVm->scene()->_abortTimersMode2 = (AbortTimerMode)dataValue;
break;
case 2:
@@ -297,7 +297,7 @@ uint16 MadsSceneLogic::startReversibleSpriteSequence(uint16 srcSpriteIdx, bool f
uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2),
spriteFrame->y + (spriteFrame->height() / 2)));
- return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
+ return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
true, 100, depth - 1, 1, ANIMTYPE_REVERSIBLE, 0, 0);
}
@@ -306,7 +306,7 @@ uint16 MadsSceneLogic::startCycledSpriteSequence(uint16 srcSpriteIdx, bool flipp
uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2),
spriteFrame->y + (spriteFrame->height() / 2)));
- return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
+ return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
true, 100, depth - 1, 1, ANIMTYPE_CYCLED, 0, 0);
}
@@ -315,7 +315,7 @@ uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, bool flipped, i
uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2),
spriteFrame->y + (spriteFrame->height() / 2)));
- return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
+ return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
true, 100, depth - 1, -1, ANIMTYPE_CYCLED, 0, 0);
}
@@ -335,11 +335,11 @@ void MadsSceneLogic::getPlayerSpritesPrefix() {
strcpy(_madsVm->_player._spritesPrefix, "RXSM");
else if (_madsVm->globals()->_nextSceneId == 112)
strcpy(_madsVm->_player._spritesPrefix, "");
-
+
if (strcmp(oldName, _madsVm->_player._spritesPrefix) != 0)
_madsVm->_player._spritesChanged = true;
- if ((_madsVm->globals()->_nextSceneId == 105) ||
+ if ((_madsVm->globals()->_nextSceneId == 105) ||
((_madsVm->globals()->_nextSceneId == 109) && (_madsVm->globals()->_globals[15] != 0))) {
// TODO: unknown flag setting
_madsVm->_player._spritesChanged = true;
@@ -420,7 +420,7 @@ void MadsSceneLogic::initializeScripts() {
if ((language != 1) || (_madsVm->getLanguage() != Common::EN_ANY))
continue;
- // Found script block for the given game and language.
+ // Found script block for the given game and language.
_scriptsSize = (i < (offsets.size() - 1)) ? offsets[i + 1] - offsets[i] : f.size() - offsets[i];
break;
}
@@ -433,7 +433,7 @@ void MadsSceneLogic::initializeScripts() {
// Load up the list of subroutines into a hash map
uint32 blockOffset = f.pos() - 3;
- uint32 subsStart = 0;
+ uint32 subsStart = 0;
for (;;) {
// Get next entry
Common::String subName;
@@ -593,12 +593,12 @@ void MadsSceneLogic::execute(uint32 subOffset) {
}
case OP_DSTORE: { // Stores data variable
- param = getParam(scriptOffset, opcode);
+ param = getParam(scriptOffset, opcode);
ScriptVar v = stack.pop();
setDataValue(param, v.isInt() ? v.get() : 0);
break;
}
-
+
case OP_LOAD: // loads local variable onto stack
param = getParam(scriptOffset, opcode);
stack.push(locals[param]);
@@ -621,7 +621,7 @@ void MadsSceneLogic::execute(uint32 subOffset) {
case OP_GSTORE: // pops stack and stores in global variable
param = getParam(scriptOffset, opcode);
- assert(param < TOTAL_NUM_VARIABLES);
+ assert(param < TOTAL_NUM_VARIABLES);
_madsVm->globals()->_globals[param] = stack.pop().get();
break;
@@ -647,7 +647,7 @@ void MadsSceneLogic::execute(uint32 subOffset) {
// Condition satisfied - do the jump
scriptOffset = param;
break;
-
+
case OP_JMPTRUE: // conditional jump
param = subOffset + getParam(scriptOffset, opcode);
if (stack.pop().get() != 0)
@@ -708,7 +708,7 @@ void MadsSceneLogic::execute(uint32 subOffset) {
case OP_OR: param1 |= param2; break;
case OP_EOR: param1 ^= param2; break;
}
-
+
stack.push(ScriptVar(param1));
}
break;
@@ -774,7 +774,7 @@ uint32 MadsSceneLogic::getParam(uint32 &scriptOffset, int opcode) {
*/
void MadsSceneLogic::getCallParameters(int numParams, Common::Stack<ScriptVar> &stack, ScriptVar *callParams) {
assert(numParams <= MAX_CALL_PARAMS);
- for (int i = 0; i < numParams; ++i, ++callParams)
+ for (int i = 0; i < numParams; ++i, ++callParams)
*callParams = stack.pop();
}
@@ -881,7 +881,7 @@ void MadsSceneLogic::callSubroutine(int subIndex, Common::Stack<ScriptVar> &stac
case 14: {
// DynamicHotspots_add
EXTRACT_PARAMS(7);
- int idx = _madsVm->scene()->_dynamicHotspots.add(p[0], p[1], p[2],
+ int idx = _madsVm->scene()->_dynamicHotspots.add(p[0], p[1], p[2],
Common::Rect(p[6], p[5], p[6] + p[4], p[5] + p[3]));
stack.push(ScriptVar(idx));
break;
diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h
index 3132094252..4f0b0d5ba2 100644
--- a/engines/m4/mads_logic.h
+++ b/engines/m4/mads_logic.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The MADS game logic is all hard-coded into the games, although for Rex at least
- * it seems to use only a fairly basic set of instructions and function calls, so it should be
- * possible
+ * it seems to use only a fairly basic set of instructions and function calls, so it should be
+ * possible
*/
#ifndef M4_MADS_LOGIC_H
diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp
index fa65329d76..8a2ab67f11 100644
--- a/engines/m4/mads_menus.cpp
+++ b/engines/m4/mads_menus.cpp
@@ -210,7 +210,7 @@ void RexMainMenuView::updateState() {
M4Sprite *spr = _menuItem->getFrame(0);
itemSize = _menuItem->getFrame(0)->height();
spr->copyTo(this, _menuItemPosList[_menuItemIndex - 1].x,
- _menuItemPosList[_menuItemIndex - 1].y + row + (itemSize / 2) - (spr->height() / 2),
+ _menuItemPosList[_menuItemIndex - 1].y + row + (itemSize / 2) - (spr->height() / 2),
spr->getTransparencyIndex());
delete _menuItem;
@@ -876,7 +876,7 @@ void RexDialogView::addLine(const char *msg_p, Font *font, MadsTextAlignment ali
}
break;
}
-
+
case RIGHT_ALIGN:
// Right align (moving left from given passed left)
rec->pos.x = left - font->getWidth(rec->text);
@@ -920,7 +920,7 @@ void RexDialogView::setClickableLines() {
for (int i = 0; i < DIALOG_LINES_SIZE; ++i) {
if (_dialogText[i].in_use) {
// Add an entry for the line
- _screenObjects.add(Common::Rect(_dialogText[i].pos.x, _dialogText[i].pos.y,
+ _screenObjects.add(Common::Rect(_dialogText[i].pos.x, _dialogText[i].pos.y,
_dialogText[i].pos.x + _dialogText[i].font->getWidth(_dialogText[i].text, _dialogText[i].widthAdjust),
_dialogText[i].pos.y + _dialogText[i].font->getHeight()), 19, i, 1);
}
@@ -988,7 +988,7 @@ RexGameMenuDialog::RexGameMenuDialog(): RexDialogView() {
void RexGameMenuDialog::addLines() {
// Add the title
int top = MADS_Y_OFFSET - 2 - ((((_vm->_font->current()->getHeight() + 2) * 6) >> 1) - 78);
-
+
addQuote(_vm->_font->current(), ALIGN_CENTER, 0, top, 10);
// Loop for adding the option lines of the dialog
@@ -1163,7 +1163,7 @@ bool RexOptionsDialog::onEvent(M4EventType eventType, int32 param1, int x, int y
return true;
}
- // Update the option selections
+ // Update the option selections
reload();
}
diff --git a/engines/m4/mads_player.cpp b/engines/m4/mads_player.cpp
index 0b83b54ff5..73480088ee 100644
--- a/engines/m4/mads_player.cpp
+++ b/engines/m4/mads_player.cpp
@@ -46,7 +46,7 @@ MadsPlayer::MadsPlayer() {
_unk4 = false;
_spritesChanged = true;
-
+
_direction = 0;
_newDirection = 0;
_priorTimer = 0;
@@ -131,7 +131,7 @@ void MadsPlayer::update() {
// Figure out the depth for the sprite
int newDepth = 1;
int yp = MIN(_playerPos.y, (int16)155);
-
+
for (int idx = 1; idx < 15; ++idx) {
if (_madsVm->scene()->getSceneResources()._depthBands[newDepth] >= yp)
newDepth = idx + 1;
@@ -199,7 +199,7 @@ void MadsPlayer::updateFrame() {
_unk2 = 0;
} else {
_unk2 = _actionList2[_actionIndex];
-
+
if (_actionIndex > 0)
--_actionIndex;
}
@@ -237,7 +237,7 @@ void MadsPlayer::setupFrame() {
_frameCount = spriteSet.getCount();
_yScale = spriteSet._charInfo->_yScale;
-
+
if ((_frameNum <= 0) || (_frameNum > _frameCount))
_frameNum = 1;
_forceRefresh = true;
@@ -336,7 +336,7 @@ void MadsPlayer::setDest(int destX, int destY, int facing) {
setTicksAmount();
_moving = true;
_destFacing = facing;
-
+
_madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 2,
_playerPos, _madsVm->scene()->_depthSurface);
_madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 1,
@@ -448,7 +448,7 @@ void MadsPlayer::move() {
bool routeFlag = false;
if (_moving) {
- int idx = _routeCount;
+ int idx = _routeCount;
while (!_v844C0 && (_destPos.x == _playerPos.x) && (_destPos.y == _playerPos.y)) {
if (idx != 0) {
--idx;
@@ -650,7 +650,7 @@ int MadsPlayer::scanPath(M4Surface *depthSurface, const Common::Point &srcPos, c
srcP += xDirection;
}
-
+
return 0;
}
@@ -730,12 +730,12 @@ void MadsPlayer::startMovement() {
int majorChange = MAX(xDiff, yDiff);
_v84530 = (majorChange == 0) ? 0 : _hypotenuse / majorChange;
-
+
if (_playerPos.x > _destPos.x)
_v8452C = MAX(_posChange.x, _posChange.y);
else
_v8452C = 0;
-
+
_hypotenuse /= 100;
_v8452E = -_v84530;
}
diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp
index a0acbdd69d..5f160aa300 100644
--- a/engines/m4/mads_scene.cpp
+++ b/engines/m4/mads_scene.cpp
@@ -169,7 +169,7 @@ void MadsScene::loadScene(int sceneNumber) {
}
_abortTimers = 0;
_abortTimersMode2 = ABORTMODE_1;
-
+
// Do any scene specific setup
if (_vm->getGameType() == GType_RexNebular)
@@ -376,7 +376,7 @@ void MadsScene::updateState() {
if (_madsVm->globals()->_config.easyMouse)
_action.refresh();
-
+
if ((_activeAnimation) && !_abortTimers) {
_activeAnimation->update();
if (((MadsAnimation *) _activeAnimation)->freeFlag() || freeFlag) {
@@ -598,7 +598,7 @@ void MadsScene::loadAnimation(const Common::String &animName, int abortTimers) {
bool MadsScene::getDepthHighBit(const Common::Point &pt) {
const byte *p = _depthSurface->getBasePtr(pt.x, pt.y);
- if (_sceneResources._depthStyle == 2)
+ if (_sceneResources._depthStyle == 2)
return ((*p << 4) & 0x80) != 0;
return (*p & 0x80) != 0;
@@ -653,7 +653,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su
_depthStyle = stream->readUint16LE();
_width = stream->readUint16LE();
_height = stream->readUint16LE();
-
+
stream->skip(24);
int nodeCount = stream->readUint16LE();
@@ -771,7 +771,7 @@ void MadsSceneResources::setRouteNode(int nodeIndex, const Common::Point &pt, M4
if (hypotenuse >= 0x3FFF)
// Shouldn't ever be this large
hypotenuse = 0x3FFF;
-
+
entry = hypotenuse | flags;
_nodes[idx].indexes[nodeIndex] = entry;
_nodes[nodeIndex].indexes[idx] = entry;
@@ -794,7 +794,7 @@ int MadsSceneResources::getRouteFlags(const Common::Point &src, const Common::Po
++yDiff;
byte *srcP = depthSurface->getBasePtr(src.x, src.y);
-
+
int totalCtr = majorDiff;
for (int xCtr = 0; xCtr < xDiff; ++xCtr, srcP += xDirection) {
totalCtr += yDiff;
@@ -837,7 +837,7 @@ int MadsSceneResources::getRouteFlags(const Common::Point &src, const Common::Po
*--------------------------------------------------------------------------
*/
-MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): GameInterfaceView(vm,
+MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): GameInterfaceView(vm,
Common::Rect(0, MADS_SURFACE_HEIGHT, vm->_screen->width(), vm->_screen->height())) {
_screenType = VIEWID_INTERFACE;
_highlightedElement = -1;
@@ -1078,7 +1078,7 @@ bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int
// A standard action was selected
int verbId = kVerbLook + (_highlightedElement - ACTIONS_START);
warning("Selected action #%d", verbId);
-
+
} else if ((_highlightedElement >= VOCAB_START) && (_highlightedElement < (VOCAB_START + 5))) {
// A vocab action was selected
MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
@@ -1259,8 +1259,8 @@ void MadsInterfaceView::leaveScene() {
//--------------------------------------------------------------------------
-int getActiveAnimationBool() {
- return (_madsVm->scene()->activeAnimation()) ? 1 : 0;
+int getActiveAnimationBool() {
+ return (_madsVm->scene()->activeAnimation()) ? 1 : 0;
}
int getAnimationCurrentFrame() {
diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp
index b66591a207..0521903c95 100644
--- a/engines/m4/mads_views.cpp
+++ b/engines/m4/mads_views.cpp
@@ -99,7 +99,7 @@ void MadsAction::set() {
// Use/to action
int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject();
MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject);
-
+
_action.objectNameId = objEntry->_descId;
_currentAction = objEntry->_vocabList[_selectedRow].vocabId;
@@ -244,7 +244,7 @@ void MadsAction::refresh() {
// Add a new text display entry to display the status text at the bottom of the screen area
uint colors = (_vm->getGameType() == GType_DragonSphere) ? 0x0300 : 0x0003;
- _statusTextIndex = _owner._textDisplay.add(160 - (strWidth / 2),
+ _statusTextIndex = _owner._textDisplay.add(160 - (strWidth / 2),
MADS_SURFACE_HEIGHT + _owner._posAdjust.y - 13, colors, textSpacing, _statusText, font);
}
}
@@ -476,7 +476,7 @@ void MadsSpriteSlots::drawBackground() {
if (slot.depth > 1) {
// Draw the frame with depth processing
- _owner._bgSurface->copyFrom(frame, xp, yp, slot.depth, _owner._depthSurface, 100,
+ _owner._bgSurface->copyFrom(frame, xp, yp, slot.depth, _owner._depthSurface, 100,
frame->getTransparencyIndex());
} else {
// No depth, so simply draw the image
@@ -526,7 +526,7 @@ void MadsSpriteSlots::drawForeground(M4Surface *viewport) {
if ((slot.scale < 100) && (slot.scale != -1)) {
// Minimalised drawing
- viewport->copyFrom(spr, slot.xp, slot.yp, slot.depth, _owner._depthSurface, slot.scale,
+ viewport->copyFrom(spr, slot.xp, slot.yp, slot.depth, _owner._depthSurface, slot.scale,
sprite->getTransparencyIndex());
} else {
int xp, yp;
@@ -665,7 +665,7 @@ void MadsTextDisplay::draw(M4Surface *view) {
for (uint idx = 0; idx < _entries.size(); ++idx) {
if (_entries[idx].active && (_entries[idx].expire >= 0)) {
_entries[idx].font->setColors(_entries[idx].color1, _entries[idx].color2, 0);
- _entries[idx].font->writeString(view, _entries[idx].msg,
+ _entries[idx].font->writeString(view, _entries[idx].msg,
_entries[idx].bounds.left, _entries[idx].bounds.top, _entries[idx].bounds.width(),
_entries[idx].spacing);
}
@@ -728,7 +728,7 @@ int MadsKernelMessageList::add(const Common::Point &pt, uint fontColor, uint8 fl
rec.frameTimer = _madsVm->_currentTimer;
rec.abortTimers = abortTimers;
rec.abortMode = _owner._abortTimersMode2;
-
+
for (int i = 0; i < 3; ++i)
rec.actionNouns[i] = _madsVm->globals()->actionNouns[i];
@@ -850,7 +850,7 @@ void MadsKernelMessageList::processText(int msgIndex) {
y1 = seqEntry.msgPos.y;
}
}
-
+
if (msg.flags & KMSG_PLAYER_TIMEOUT) {
if (word_8469E != 0) {
// TODO: Figure out various flags
@@ -867,7 +867,7 @@ void MadsKernelMessageList::processText(int msgIndex) {
msg.msg[msg.msgOffset] = msg.asciiChar;
char *msgP = &msg.msg[++msg.msgOffset];
*msgP = msg.asciiChar2;
-
+
msg.asciiChar = *msgP;
msg.asciiChar2 = *(msgP + 1);
@@ -884,7 +884,7 @@ void MadsKernelMessageList::processText(int msgIndex) {
flag = true;
}
- int strWidth = _talkFont->getWidth(msg.msg, _owner._textSpacing);
+ int strWidth = _talkFont->getWidth(msg.msg, _owner._textSpacing);
if (msg.flags & (KMSG_RIGHT_ALIGN | KMSG_CENTER_ALIGN)) {
x1 -= (msg.flags & KMSG_CENTER_ALIGN) ? strWidth / 2 : strWidth;
@@ -935,7 +935,7 @@ ScreenObjects::ScreenObjects(MadsView &owner): _owner(owner) {
_category = 0;
_objectIndex = 0;
}
-
+
/**
* Clears the entries list
*/
@@ -1153,7 +1153,7 @@ void MadsDirtyAreas::setSpriteSlot(int dirtyIdx, const MadsSpriteSlot &spriteSlo
SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(spriteSlot.spriteListIndex);
M4Sprite *frame = spriteSet.getFrame(((spriteSlot.frameNumber & 0x7fff) - 1) & 0x7f);
-
+
if (spriteSlot.scale == -1) {
width = frame->width();
height = frame->height();
@@ -1270,8 +1270,8 @@ bool MadsSequenceList::addSubEntry(int index, SequenceSubEntryMode mode, int fra
return false;
}
-int MadsSequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks,
- int msgX, int msgY, bool nonFixed, char scale, uint8 depth, int frameInc, SpriteAnimType animType, int numSprites,
+int MadsSequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks,
+ int msgX, int msgY, bool nonFixed, char scale, uint8 depth, int frameInc, SpriteAnimType animType, int numSprites,
int frameStart) {
// Find a free slot
@@ -1340,7 +1340,7 @@ void MadsSequenceList::setSpriteSlot(int seqIndex, MadsSpriteSlot &spriteSlot) {
spriteSlot.frameNumber = (timerEntry.flipped ? 0x8000 : 0) | timerEntry.frameIndex;
spriteSlot.depth = timerEntry.depth;
spriteSlot.scale = timerEntry.scale;
-
+
if (!timerEntry.nonFixed) {
spriteSlot.xp = timerEntry.msgPos.x;
spriteSlot.yp = timerEntry.msgPos.y;
@@ -1420,7 +1420,7 @@ bool MadsSequenceList::loadSprites(int seqIndex) {
seqEntry.frameInc = 1;
} else {
// Otherwise reset back to last sprite for further reverse animating
- seqEntry.frameIndex = seqEntry.numSprites;
+ seqEntry.frameIndex = seqEntry.numSprites;
}
}
@@ -1478,7 +1478,7 @@ void MadsSequenceList::tick() {
continue;
// Set the next timeout for the timer entry
- seqEntry.timeout = currentTimer + seqEntry.numTicks;
+ seqEntry.timeout = currentTimer + seqEntry.numTicks;
// Action the sprite
if (loadSprites(idx)) {
@@ -1509,7 +1509,7 @@ void MadsSequenceList::setAnimRange(int seqIndex, int startVal, int endVal) {
tempStart = 1;
break;
}
-
+
switch (endVal) {
case -2:
case 0:
@@ -1558,7 +1558,7 @@ Animation::~Animation() {
MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceList(*this),
_kernelMessages(*this), _spriteSlots(*this), _dirtyAreas(*this), _textDisplay(*this),
_screenObjects(*this), _action(*this) {
-
+
_textSpacing = -1;
_newTimeout = 0;
_abortTimers = 0;
@@ -1590,8 +1590,8 @@ void MadsView::refresh() {
// Merge any identified dirty areas
_dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
-
- // Copy dirty areas to the main display surface
+
+ // Copy dirty areas to the main display surface
_dirtyAreas.copy(_viewport, _bgSurface, _posAdjust);
// Handle dirty areas for foreground objects
diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h
index 6be2283a32..41caaa2ded 100644
--- a/engines/m4/mads_views.h
+++ b/engines/m4/mads_views.h
@@ -208,7 +208,7 @@ public:
#define TIMED_TEXT_SIZE 10
#define INDEFINITE_TIMEOUT 9999999
-enum KernelMessageFlags {KMSG_QUOTED = 1, KMSG_PLAYER_TIMEOUT = 2, KMSG_SEQ_ENTRY = 4, KMSG_SCROLL = 8, KMSG_RIGHT_ALIGN = 0x10,
+enum KernelMessageFlags {KMSG_QUOTED = 1, KMSG_PLAYER_TIMEOUT = 2, KMSG_SEQ_ENTRY = 4, KMSG_SCROLL = 8, KMSG_RIGHT_ALIGN = 0x10,
KMSG_CENTER_ALIGN = 0x20, KMSG_EXPIRE = 0x40, KMSG_ACTIVE = 0x80};
class MadsKernelMessageEntry {
@@ -388,7 +388,7 @@ struct MadsSequenceEntry {
int8 active;
int8 spriteListIndex;
bool flipped;
-
+
int frameIndex;
int frameStart;
int numSprites;
@@ -402,7 +402,7 @@ struct MadsSequenceEntry {
bool nonFixed;
int field_13;
-
+
Common::Point msgPos;
int triggerCountdown;
bool doneFlag;
@@ -424,10 +424,10 @@ private:
public:
MadsSequenceList(MadsView &owner);
- MadsSequenceEntry &operator[](int index) { return _entries[index]; }
+ MadsSequenceEntry &operator[](int index) { return _entries[index]; }
void clear();
bool addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal);
- int add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks,
+ int add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks,
int extraTicks, int numTicks, int msgX, int msgY, bool nonFixed, char scale, uint8 depth,
int frameInc, SpriteAnimType animType, int numSprites, int frameStart);
void remove(int seqIndex);
@@ -452,7 +452,7 @@ public:
virtual void setCurrentFrame(int frameNumber) = 0;
virtual int getCurrentFrame() = 0;
};
-
+
class MadsView {
private:
diff --git a/engines/m4/resource.cpp b/engines/m4/resource.cpp
index 2ae29ca0bb..f5b2050052 100644
--- a/engines/m4/resource.cpp
+++ b/engines/m4/resource.cpp
@@ -313,7 +313,7 @@ const char *MADSResourceManager::getResourceFilename(const char *resourceName) {
/**
* Forms a resource name based on the passed specifiers
*/
-const char *MADSResourceManager::getResourceName(char asciiCh, int prefix, ExtensionType extType,
+const char *MADSResourceManager::getResourceName(char asciiCh, int prefix, ExtensionType extType,
const char *suffix, int index) {
static char resourceName[100];
diff --git a/engines/m4/resource.h b/engines/m4/resource.h
index 00c54a3680..c13c293544 100644
--- a/engines/m4/resource.h
+++ b/engines/m4/resource.h
@@ -109,7 +109,7 @@ public:
enum ResourceType {RESTYPE_ROOM, RESTYPE_SC, RESTYPE_TEXT, RESTYPE_QUO, RESTYPE_I,
RESTYPE_OB, RESTYPE_FONT, RESTYPE_SOUND, RESTYPE_SPEECH, RESTYPE_HAS_EXT, RESTYPE_NO_EXT};
-enum ExtensionType {EXTTYPE_SS = 1, EXTTYPE_AA = 2, EXTTYPE_DAT = 3, EXTTYPE_HH = 4, EXTTYPE_ART = 5,
+enum ExtensionType {EXTTYPE_SS = 1, EXTTYPE_AA = 2, EXTTYPE_DAT = 3, EXTTYPE_HH = 4, EXTTYPE_ART = 5,
EXTTYPE_INT = 6, EXTTYPE_NONE = -1};
enum ResourcePrefixType {RESPREFIX_GL = 1, RESPREFIX_SC = 2, RESPREFIX_RM = 3};
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
index a38be20086..be49dcb13f 100644
--- a/engines/m4/scene.cpp
+++ b/engines/m4/scene.cpp
@@ -36,7 +36,7 @@
namespace M4 {
-Scene::Scene(MadsM4Engine *vm, SceneResources *res): View(vm, Common::Rect(0, 0, vm->_screen->width(),
+Scene::Scene(MadsM4Engine *vm, SceneResources *res): View(vm, Common::Rect(0, 0, vm->_screen->width(),
vm->_screen->height())), _sceneResources(res) {
_screenType = VIEWID_SCENE;
@@ -142,7 +142,7 @@ void Scene::showCodes() {
// Show the walk areas for the M4 engine in black and white
const byte *srcP = (const byte *)_walkSurface->getBasePtr(0, 0);
byte *destP = _backgroundSurface->getBasePtr(0, 0);
-
+
for (int i = 0; i < _walkSurface->width() * _walkSurface->height(); i++)
destP[i] = (srcP[i] & 0x10) ? 0xFF : 0;
@@ -154,7 +154,7 @@ void Scene::showCodes() {
_vm->_palette->setPalette(colors, 0, 256);
} else {
// MADS handling
-
+
// copy the walk data to the background, in whatever current palette is active
_walkSurface->copyTo(_backgroundSurface);
diff --git a/engines/m4/sound.cpp b/engines/m4/sound.cpp
index d10dea5cad..76eae8a661 100644
--- a/engines/m4/sound.cpp
+++ b/engines/m4/sound.cpp
@@ -97,8 +97,8 @@ void Sound::playSound(const char *soundName, int volume, bool loop, int channel)
_mixer->playStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume);
}
-void Sound::playSound(int soundNum) {
- warning("TODO: playSound(%d)", soundNum);
+void Sound::playSound(int soundNum) {
+ warning("TODO: playSound(%d)", soundNum);
}
void Sound::pauseSound() {
diff --git a/engines/m4/sprite.cpp b/engines/m4/sprite.cpp
index 1a3228d1bb..d0741732f3 100644
--- a/engines/m4/sprite.cpp
+++ b/engines/m4/sprite.cpp
@@ -182,7 +182,7 @@ void M4Sprite::loadMadsSprite(Common::SeekableReadStream* source) {
}
}
}
-
+
// Check if we need to scan forward to find the end of the line
if (!newLine) {
do {
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index 1151339d49..004f1462a6 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -511,7 +511,7 @@ int16 GameDatabaseV2::loadgame(const char *filename, int16 version) {
_objects[i]->load(*in);
}
delete in;
-
+
_objectPropertyCache.clear(); // make sure to clear cache
return result;
}
@@ -642,7 +642,7 @@ void GameDatabaseV3::load(Common::SeekableReadStream &sourceS) {
void GameDatabaseV3::reloadFromStream(Common::SeekableReadStream &sourceS) {
sourceS.seek(_gameStateOffs);
sourceS.read(_gameState, _gameStateSize);
-
+
_objectPropertyCache.clear(); // make sure to clear cache
}
@@ -734,9 +734,9 @@ int16 GameDatabaseV3::loadgame(const char *filename, int16 version) {
in->skip(64); // skip savegame description
in->read(_gameState, _gameStateSize);
delete in;
-
+
_objectPropertyCache.clear(); // make sure to clear cache
-
+
return 0;
}
diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp
index 4576e2b5ce..e8c948af4e 100644
--- a/engines/made/detection.cpp
+++ b/engines/made/detection.cpp
@@ -525,34 +525,11 @@ static MadeGameDescription g_fallbackDesc = {
} // End of namespace Made
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Made::gameDescriptions,
- // Size of that superset structure
- sizeof(Made::MadeGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- madeGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "made",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class MadeMetaEngine : public AdvancedMetaEngine {
public:
- MadeMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ MadeMetaEngine() : AdvancedMetaEngine(Made::gameDescriptions, sizeof(Made::MadeGameDescription), madeGames) {
+ _singleid = "made";
+ }
virtual const char *getName() const {
return "MADE";
@@ -565,7 +542,7 @@ public:
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
- const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const;
+ const ADGameDescription *fallbackDetect(const Common::FSList &fslist, const FileMap &allFiles) const;
};
@@ -587,7 +564,7 @@ bool MadeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
return gd != 0;
}
-const ADGameDescription *MadeMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
+const ADGameDescription *MadeMetaEngine::fallbackDetect(const Common::FSList &fslist, const FileMap &allFiles) const {
// Set the default values for the fallback descriptor's ADGameDescription part.
Made::g_fallbackDesc.desc.language = Common::UNK_LANG;
Made::g_fallbackDesc.desc.platform = Common::kPlatformPC;
diff --git a/engines/module.mk b/engines/module.mk
index 643310002f..7849c2ff25 100644
--- a/engines/module.mk
+++ b/engines/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
dialogs.o \
engine.o \
game.o \
+ obsolete.o \
savestate.o
# Include common rules
diff --git a/engines/mohawk/bitmap.cpp b/engines/mohawk/bitmap.cpp
index d54e2dac6b..f61516c91d 100644
--- a/engines/mohawk/bitmap.cpp
+++ b/engines/mohawk/bitmap.cpp
@@ -910,7 +910,7 @@ void DOSBitmap::expandEGAPlanes(Graphics::Surface *surface, Common::SeekableRead
j = -1;
x++;
}
- }
+ }
dst += surface->w;
}
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 4e5b7186ff..05012bec3d 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -632,7 +632,7 @@ bool RivenConsole::Cmd_Combos(int argc, const char **argv) {
uint32 teleCombo = _vm->_vars["tcorrectorder"];
uint32 prisonCombo = _vm->_vars["pcorrectorder"];
uint32 domeCombo = _vm->_vars["adomecombo"];
-
+
DebugPrintf("Telescope Combo:\n ");
for (int i = 0; i < 5; i++)
DebugPrintf("%d ", _vm->_externalScriptHandler->getComboDigit(teleCombo, i));
diff --git a/engines/mohawk/cstime.cpp b/engines/mohawk/cstime.cpp
index 59bc5ad661..3f9827581b 100644
--- a/engines/mohawk/cstime.cpp
+++ b/engines/mohawk/cstime.cpp
@@ -217,7 +217,7 @@ void MohawkEngine_CSTime::nextScene() {
void MohawkEngine_CSTime::loadResourceFile(Common::String name) {
MohawkArchive *archive = new MohawkArchive();
- if (!archive->open(name + ".mhk"))
+ if (!archive->openFile(name + ".mhk"))
error("failed to open %s.mhk", name.c_str());
_mhk.push_back(archive);
}
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index f95084de8e..3284a3228f 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -234,7 +234,7 @@ LivingBooksCursorManager_v2::LivingBooksCursorManager_v2() {
// Try to open the system archive if we have it
_sysArchive = new MohawkArchive();
- if (!_sysArchive->open("system.mhk")) {
+ if (!_sysArchive->openFile("system.mhk")) {
delete _sysArchive;
_sysArchive = 0;
}
@@ -274,6 +274,7 @@ void PECursorManager::setCursor(uint16 id) {
Graphics::WinCursor *cursor = cursorGroup->cursors[0].cursor;
CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor());
CursorMan.replaceCursorPalette(cursor->getPalette(), 0, 256);
+ delete cursorGroup;
return;
}
}
diff --git a/engines/mohawk/detection.cpp b/engines/mohawk/detection.cpp
index 6a73b28246..f0c657897d 100644
--- a/engines/mohawk/detection.cpp
+++ b/engines/mohawk/detection.cpp
@@ -158,34 +158,17 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Mohawk::gameDescriptions,
- // Size of that superset structure
- sizeof(Mohawk::MohawkGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- mohawkGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "mohawk",
- // List of files for file-based fallback detection (optional)
- Mohawk::fileBased,
- // Flags
- 0,
- // Additional GUI options (for every game)
- Common::GUIO_NONE,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class MohawkMetaEngine : public AdvancedMetaEngine {
public:
- MohawkMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ MohawkMetaEngine() : AdvancedMetaEngine(Mohawk::gameDescriptions, sizeof(Mohawk::MohawkGameDescription), mohawkGames) {
+ _singleid = "mohawk";
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ }
+
+ virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
+ return detectGameFilebased(allFiles, Mohawk::fileBased);
+ }
virtual const char *getName() const {
return "Mohawk";
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index df66c3dc1c..2243dd1c1d 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -33,7 +33,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "ae3258c9c90128d274aa6a790b3ad181"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -51,7 +51,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("DEMO.DAT", "c39303dd53fb5c4e7f3c23231c606cd0"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -69,7 +69,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "4beb3366ed3f3b9bfb6e81a14a43bdcc"),
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -87,7 +87,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "e0937cca1ab125e48e30dc3cd5046ddf"),
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -105,7 +105,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "f7e7d7ca69934f1351b5acd4fe4d44c2"),
Common::ES_ESP,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -123,7 +123,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "032c88e3b7e8db4ca475e7b7db9a66bb"),
Common::JA_JPN,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -141,7 +141,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "d631d42567a941c67c78f2e491f4ea58"),
Common::FR_FRA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -159,7 +159,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MAKING.DAT", "f6387e8f0f7b8a3e42c95294315d6a0e"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MAKINGOF,
@@ -177,7 +177,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MAKING.DAT", "03ff62607e64419ab2b6ebf7b7bcdf63"),
Common::JA_JPN,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MAKINGOF,
@@ -195,7 +195,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "c4cae9f143b5947262e6cb2397e1617e"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -213,7 +213,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "c4cae9f143b5947262e6cb2397e1617e"),
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -231,7 +231,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "f88e0ace66dbca78eebdaaa1d3314ceb"),
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -249,7 +249,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MYST.DAT", "aea81633b2d2ae498f09072fb87263b6"),
Common::FR_FRA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -267,7 +267,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("a_Data.MHK", "71145fdecbd68a0cfc292c2fbddf8e08"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -285,7 +285,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("a_Data.MHK", "d8ccae34a0e3c709135a73f449b783be"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -303,7 +303,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("a_Data.MHK", "249e8c995d191b03ee94c892c0eac775"),
Common::ES_ESP,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -321,7 +321,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("a_Data.MHK", "08fcaa5d5a2a01d7a5a6960f497212fe"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -339,7 +339,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("a_Data.MHK", "a5fe1c91a6033eb6ee54b287578b74b9"),
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -357,7 +357,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("a_Data.MHK", "aff2a384aaa9a0e0ec51010f708c5c04"),
Common::FR_FRA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -375,7 +375,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("a_Data.MHK", "bae6b03bd8d6eb350d35fd13f0e3139f"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -390,7 +390,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("signin.mhk", "410b4ce8d1a8702971e4d1ffba9b965d"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_CSTIME,
@@ -405,7 +405,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("iface.mhk", "5c1203712a16513bd158dc3c1b6cebd7"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_DEMO,
+ ADGF_DEMO | ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_CSTIME,
@@ -421,7 +421,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("ZOOMBINI.MHK", "98b758fec55104c096cfd129048be9a6"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_ZOOMBINI,
@@ -436,6 +436,21 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("ZOOMBINI.MHK", "0672f65c40dd065840c896e41c13f980"),
Common::EN_ANY,
Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ Common::GUIO_NONE
+ },
+ GType_ZOOMBINI,
+ GF_HASMIDI,
+ 0
+ },
+
+ {
+ {
+ "zoombini",
+ "v2.0",
+ AD_ENTRY1("ZOOMBINI.MHK", "506b1122ffa740e2566cf0b583d24478"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
ADGF_NO_FLAGS,
Common::GUIO_NONE
},
@@ -451,7 +466,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("ZOOMBINI.MHK", "6ae0bdf791266b1fe3d4fabbf44c3faa"),
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_ZOOMBINI,
@@ -466,7 +481,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("ZOOMBINI.MHK", "8231e58525143ccf6e8b747df34b139f"),
Common::FR_FRA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_ZOOMBINI,
@@ -481,7 +496,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("C2K.MHK", "605fe88380848031bbd0ff84ade6fe40"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_CSWORLD,
@@ -496,7 +511,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("C2K.MHK", "d4857aeb0f5e2e0c4ac556aa74f38c23"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_CSWORLD,
@@ -511,7 +526,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("AMTRAK.MHK", "2f95301f0bb950d555bb7b0e3b1b7eb1"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_CSAMTRAK,
@@ -645,7 +660,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("Outline.txt", "67abce5dcda969c23f367a98c90439bc"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV5,
@@ -660,7 +675,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("Outline.txt", "6a281eefe72987afb0f8fb6cf84553f5"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV5,
@@ -675,7 +690,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("Outline", "b7dc6e65fa9e80784a5bb8b557aa37c4"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -690,7 +705,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("BookOutline", "1ce006d7daaa26cf61040203856b88f1"),
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -705,7 +720,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("BRODER.MHK", "007299da8b2c6e8ec1cde9598c243024"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_JAMESMATH,
@@ -721,7 +736,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("BRODER.MHK", "53c000938a50dca92860fd9b546dd276"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_JAMESMATH,
@@ -736,7 +751,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("MAINROOM.MHK", "12f51894d7f838af639ea9bf1bc8f45b"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_TREEHOUSE,
@@ -858,7 +873,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("AL236_1.MHK", "3ba145492a7b8b4dee0ef4222c5639c3"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_1STDEGREE,
@@ -876,7 +891,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("AL236_1.MHK", "0e0c70b1b702b6ddca61a1192ada1282"),
Common::FR_FRA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_1STDEGREE,
@@ -891,7 +906,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("USAC2K.MHK", "b8c9d3a2586f62bce3a48b50d7a700e9"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_CSUSA,
@@ -1435,7 +1450,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("RACE.LB", "1645f36bcb36e440d928e920aa48c373"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -1451,7 +1466,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("RACE32.LB", "292a05bc48c1dd9583821a4181a02ef2"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -1686,7 +1701,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("Outline", "0b5ab6dd7c08cf23066efa709fa48bbc"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -1701,7 +1716,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("BookOutline", "e139903eee98f0b0c3f39247a23b8f10"),
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -1716,7 +1731,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("outline", "525be248363fe27d50d750632c1e759e"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV4,
@@ -1731,7 +1746,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("BookOutline", "54a324ee6f8260258bff7043a05b0004"),
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV4,
@@ -1749,7 +1764,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("outline", "36225e0b4986a80135cfdd9643cc7030"),
Common::FR_FRA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV4,
@@ -1825,7 +1840,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("outline", "d239506f969ff68fa886f084082e9158"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -1840,7 +1855,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("BookOutline", "6dd1c0606f1db3b71207121b4370e487"),
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV3,
@@ -1934,7 +1949,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("OUTLINE", "dec4d1a05449f81b6012706932658326"),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV4,
@@ -1949,7 +1964,7 @@ static const MohawkGameDescription gameDescriptions[] = {
AD_ENTRY1("BookOutline", "87bf1f9113340ce1c6c880932e815882"),
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV4,
@@ -2150,7 +2165,7 @@ static const MohawkGameDescription fallbackDescs[] = {
AD_ENTRY1(0, 0),
Common::UNK_LANG,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -2165,7 +2180,7 @@ static const MohawkGameDescription fallbackDescs[] = {
AD_ENTRY1(0, 0),
Common::UNK_LANG,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MAKINGOF,
@@ -2180,7 +2195,7 @@ static const MohawkGameDescription fallbackDescs[] = {
AD_ENTRY1(0, 0),
Common::UNK_LANG,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_MYST,
@@ -2195,7 +2210,7 @@ static const MohawkGameDescription fallbackDescs[] = {
AD_ENTRY1(0, 0),
Common::UNK_LANG,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -2210,7 +2225,7 @@ static const MohawkGameDescription fallbackDescs[] = {
AD_ENTRY1(0, 0),
Common::UNK_LANG,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
GType_RIVEN,
@@ -2220,11 +2235,11 @@ static const MohawkGameDescription fallbackDescs[] = {
};
static const ADFileBasedFallback fileBased[] = {
- { &fallbackDescs[0], { "MYST.DAT", 0 } },
- { &fallbackDescs[1], { "MAKING.DAT", 0 } },
- { &fallbackDescs[2], { "MYST.DAT", "Help.dat", 0 } }, // Help system doesn't exist in original
- { &fallbackDescs[3], { "a_Data.MHK", 0 } },
- { &fallbackDescs[4], { "a_Data.MHK", "t_Data1.MHK" , 0 } },
+ { &fallbackDescs[0].desc, { "MYST.DAT", 0 } },
+ { &fallbackDescs[1].desc, { "MAKING.DAT", 0 } },
+ { &fallbackDescs[2].desc, { "MYST.DAT", "Help.dat", 0 } }, // Help system doesn't exist in original
+ { &fallbackDescs[3].desc, { "a_Data.MHK", 0 } },
+ { &fallbackDescs[4].desc, { "a_Data.MHK", "t_Data1.MHK" , 0 } },
{ 0, { 0 } }
};
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index 375806cda4..06500bc725 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -32,6 +32,7 @@
#include "common/archive.h"
#include "common/textconsole.h"
#include "common/system.h"
+#include "common/memstream.h"
#include "graphics/palette.h"
@@ -42,7 +43,7 @@
namespace Mohawk {
// read a null-terminated string from a stream
-Common::String MohawkEngine_LivingBooks::readString(Common::SeekableSubReadStreamEndian *stream) {
+Common::String MohawkEngine_LivingBooks::readString(Common::ReadStream *stream) {
Common::String ret;
while (!stream->eos()) {
byte in = stream->readByte();
@@ -54,7 +55,7 @@ Common::String MohawkEngine_LivingBooks::readString(Common::SeekableSubReadStrea
}
// read a rect from a stream
-Common::Rect MohawkEngine_LivingBooks::readRect(Common::SeekableSubReadStreamEndian *stream) {
+Common::Rect MohawkEngine_LivingBooks::readRect(Common::ReadStreamEndian *stream) {
Common::Rect rect;
// the V1 mac games have their rects in QuickDraw order
@@ -81,7 +82,7 @@ LBPage::LBPage(MohawkEngine_LivingBooks *vm) : _vm(vm) {
_cascade = false;
}
-void LBPage::open(MohawkArchive *mhk, uint16 baseId) {
+void LBPage::open(Archive *mhk, uint16 baseId) {
_mhk = mhk;
_baseId = baseId;
@@ -384,8 +385,8 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
warning("ignoring 'killgag' for filename '%s'", filename.c_str());
}
- MohawkArchive *pageArchive = createMohawkArchive();
- if (!filename.empty() && pageArchive->open(filename)) {
+ Archive *pageArchive = createArchive();
+ if (!filename.empty() && pageArchive->openFile(filename)) {
_page = new LBPage(this);
_page->open(pageArchive, 1000);
} else {
@@ -589,11 +590,11 @@ void MohawkEngine_LivingBooks::updatePage() {
}
}
-void MohawkEngine_LivingBooks::addArchive(MohawkArchive *archive) {
+void MohawkEngine_LivingBooks::addArchive(Archive *archive) {
_mhk.push_back(archive);
}
-void MohawkEngine_LivingBooks::removeArchive(MohawkArchive *archive) {
+void MohawkEngine_LivingBooks::removeArchive(Archive *archive) {
for (uint i = 0; i < _mhk.size(); i++) {
if (archive != _mhk[i])
continue;
@@ -767,6 +768,8 @@ void LBPage::loadBITL(uint16 resourceId) {
if (bitlStream->size() == bitlStream->pos())
break;
}
+
+ delete bitlStream;
}
Common::SeekableSubReadStreamEndian *MohawkEngine_LivingBooks::wrapStreamEndian(uint32 tag, uint16 id) {
@@ -862,8 +865,11 @@ Common::String MohawkEngine_LivingBooks::convertWinFileName(const Common::String
return filename;
}
-MohawkArchive *MohawkEngine_LivingBooks::createMohawkArchive() const {
- return isPreMohawk() ? new LivingBooksArchive_v1() : new MohawkArchive();
+Archive *MohawkEngine_LivingBooks::createArchive() const {
+ if (isPreMohawk())
+ return new LivingBooksArchive_v1();
+
+ return new MohawkArchive();
}
bool MohawkEngine_LivingBooks::isPreMohawk() const {
@@ -1873,6 +1879,7 @@ uint16 LBAnimation::getParentId() {
LBScriptEntry::LBScriptEntry() {
state = 0;
+ data = NULL;
argvParam = NULL;
argvTarget = NULL;
}
@@ -1880,6 +1887,7 @@ LBScriptEntry::LBScriptEntry() {
LBScriptEntry::~LBScriptEntry() {
delete[] argvParam;
delete[] argvTarget;
+ delete[] data;
for (uint i = 0; i < subentries.size(); i++)
delete subentries[i];
@@ -1943,7 +1951,10 @@ void LBItem::readFrom(Common::SeekableSubReadStreamEndian *stream) {
uint16 dataSize = stream->readUint16();
debug(4, "Data type %04x, size %d", dataType, dataSize);
- readData(dataType, dataSize, stream);
+ byte *buf = new byte[dataSize];
+ stream->read(buf, dataSize);
+ readData(dataType, dataSize, buf);
+ delete[] buf;
if ((uint)stream->pos() != oldPos + 4 + (uint)dataSize)
error("Failed to read correct number of bytes (off by %d) for data type %04x (size %d)",
@@ -1956,7 +1967,7 @@ void LBItem::readFrom(Common::SeekableSubReadStreamEndian *stream) {
}
}
-LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::SeekableSubReadStreamEndian *stream, bool isSubentry) {
+LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::MemoryReadStreamEndian *stream, bool isSubentry) {
if (size < 6)
error("Script entry of type 0x%04x was too small (%d)", type, size);
@@ -1999,30 +2010,40 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Seeka
entry->argc = stream->readUint16();
size -= 2;
+ entry->targetingType = 0;
+
uint16 targetingType = entry->argc;
- if (targetingType == 0x3f3f || targetingType == 0xffff) {
- entry->argc = 0;
+ if (targetingType == kTargetTypeExpression || targetingType == kTargetTypeCode
+ || targetingType == kTargetTypeName) {
+ entry->targetingType = targetingType;
+
+ // FIXME
+ if (targetingType == kTargetTypeCode)
+ error("encountered kTargetTypeCode");
+ if (size < 2)
+ error("not enough bytes (%d) reading special targeting", size);
uint16 count = stream->readUint16();
size -= 2;
debug(4, "%d targets with targeting type %04x", count, targetingType);
- // FIXME: targeting by name
uint oldAlign = size % 2;
for (uint i = 0; i < count; i++) {
Common::String target = _vm->readString(stream);
- warning("ignoring target '%s' in script entry", target.c_str());
+ debug(4, "target '%s'", target.c_str());
+ entry->targets.push_back(target);
+ if (target.size() + 1 > size)
+ error("failed to read target (ran out of stream)");
size -= target.size() + 1;
}
+ entry->argc = entry->targets.size();
if ((uint)(size % 2) != oldAlign) {
stream->skip(1);
size--;
}
- }
-
- if (entry->argc) {
+ } else if (entry->argc) {
entry->argvParam = new uint16[entry->argc];
entry->argvTarget = new uint16[entry->argc];
debug(4, "With %d targets:", entry->argc);
@@ -2075,37 +2096,33 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Seeka
debug(4, "kLBOpSendExpression: offset %08x", entry->offset);
size -= 4;
}
- if (entry->opcode == 0xffff) {
+ if (entry->opcode == kLBOpRunData) {
if (size < 4)
- error("didn't get enough bytes (%d) to read message in script entry", size);
- uint16 msgId = stream->readUint16();
- uint16 msgLen = stream->readUint16();
+ error("didn't get enough bytes (%d) to read data header in script entry", size);
+ entry->dataType = stream->readUint16();
+ entry->dataLen = stream->readUint16();
size -= 4;
- if (msgId == kLBSetPlayInfo) {
- if (size != 20)
- error("wah, more than just the kLBSetPlayInfo in here");
- // FIXME
- warning("ignoring kLBSetPlayInfo");
- size -= 20;
- stream->skip(20);
- return entry;
- }
- if (msgId != kLBCommand)
- error("expected a command in script entry, got 0x%04x", msgId);
+ if (size < entry->dataLen)
+ error("didn't get enough bytes (%d) to read data in script entry", size);
- if (msgLen != size - (entry->event == kLBEventNotified ? 4 : 0) && !conditionTag)
- error("script entry msgLen %d is not equal to size %d", msgLen, size);
-
- Common::String command = _vm->readString(stream);
- if (command.size() + 1 > size) {
- error("failed to read command in script entry: msgLen %d, command '%s' (%d chars)",
- msgLen, command.c_str(), command.size());
+ if (entry->dataType == kLBCommand) {
+ Common::String command = _vm->readString(stream);
+ uint commandSize = command.size() + 1;
+ if (commandSize > entry->dataLen)
+ error("failed to read command in script entry: dataLen %d, command '%s' (%d chars)",
+ entry->dataLen, command.c_str(), commandSize);
+ entry->dataLen = commandSize;
+ entry->data = new byte[commandSize];
+ memcpy(entry->data, command.c_str(), commandSize);
+ size -= commandSize;
+ } else {
+ if (conditionTag)
+ error("kLBOpRunData had unexpected conditionTag");
+ entry->data = new byte[entry->dataLen];
+ stream->read(entry->data, entry->dataLen);
+ size -= entry->dataLen;
}
- size -= command.size() + 1;
-
- entry->command = command;
- debug(4, "script entry command '%s'", command.c_str());
}
if (entry->event == kLBEventNotified) {
if (size < 4)
@@ -2126,6 +2143,8 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Seeka
}
if (conditionTag == 1) {
+ if (!size)
+ error("failed to read condition (empty stream)");
Common::String condition = _vm->readString(stream);
if (condition.size() == 0) {
size--;
@@ -2140,6 +2159,8 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Seeka
entry->conditions.push_back(condition);
debug(4, "script entry condition '%s'", condition.c_str());
} else if (conditionTag == 2) {
+ if (size < 4)
+ error("expected more than %d bytes for conditionTag 2", size);
// FIXME
stream->skip(4);
size -= 4;
@@ -2156,7 +2177,12 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Seeka
return entry;
}
-void LBItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream) {
+void LBItem::readData(uint16 type, uint16 size, byte *data) {
+ Common::MemoryReadStreamEndian stream(data, size, _vm->isBigEndian());
+ readData(type, size, &stream);
+}
+
+void LBItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream) {
switch (type) {
case kLBMsgListScript:
case kLBNotifyScript:
@@ -2612,15 +2638,59 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
entry->type, entry->event, entry->opcode, entry->param);
if (entry->argc) {
- uint16 targetId = entry->argvTarget[n];
- // TODO: is this type, perhaps?
- uint16 param = entry->argvParam[n];
- target = _vm->getItemById(targetId);
- if (!target) {
- debug(2, "Target %04x (%04x) doesn't exist, skipping", targetId, param);
- continue;
+ switch (entry->targetingType) {
+ case kTargetTypeExpression:
+ {
+ // FIXME: this should be EVALUATED
+ LBValue &tgt = _vm->_variables[entry->targets[n]];
+ switch (tgt.type) {
+ case kLBValueItemPtr:
+ target = tgt.item;
+ break;
+ case kLBValueString:
+ // FIXME: handle 'self', at least
+ // TODO: correct otherwise? or only self?
+ target = _vm->getItemByName(tgt.string);
+ break;
+ case kLBValueInteger:
+ target = _vm->getItemById(tgt.integer);
+ break;
+ default:
+ // FIXME: handle list
+ warning("Target '%s' (by expression) resulted in unknown type, skipping", entry->targets[n].c_str());
+ continue;
+ }
+ }
+ if (!target) {
+ debug(2, "Target '%s' (by expression) doesn't exist, skipping", entry->targets[n].c_str());
+ continue;
+ }
+ debug(2, "Target: '%s' (expression '%s')", target->_desc.c_str(), entry->targets[n].c_str());
+ break;
+ case kTargetTypeCode:
+ // FIXME
+ error("encountered kTargetTypeCode");
+ break;
+ case kTargetTypeName:
+ // FIXME: handle 'self'
+ target = _vm->getItemByName(entry->targets[n]);
+ if (!target) {
+ debug(2, "Target '%s' (by name) doesn't exist, skipping", entry->targets[n].c_str());
+ continue;
+ }
+ debug(2, "Target: '%s' (by name)", target->_desc.c_str());
+ break;
+ default:
+ uint16 targetId = entry->argvTarget[n];
+ // TODO: is this type, perhaps?
+ uint16 param = entry->argvParam[n];
+ target = _vm->getItemById(targetId);
+ if (!target) {
+ debug(2, "Target %04x (%04x) doesn't exist, skipping", targetId, param);
+ continue;
+ }
+ debug(2, "Target: %04x (%04x) '%s'", targetId, param, target->_desc.c_str());
}
- debug(2, "Target: %04x (%04x) '%s'", targetId, param, target->_desc.c_str());
} else {
target = this;
debug(2, "Self-target on '%s'", _desc.c_str());
@@ -2781,8 +2851,8 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
}
break;
- case kLBOpRunCommand:
- runCommand(entry->command);
+ case kLBOpRunData:
+ readData(entry->dataType, entry->dataLen, entry->data);
break;
case kLBOpJumpUnlessExpression:
@@ -3118,7 +3188,7 @@ LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rec
_starting = false;
}
-void LBGroupItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream) {
+void LBGroupItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream) {
switch (type) {
case kLBGroupData:
{
@@ -3239,7 +3309,7 @@ LBPaletteItem::~LBPaletteItem() {
delete[] _palette;
}
-void LBPaletteItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream) {
+void LBPaletteItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream) {
switch (type) {
case kLBPaletteXData:
{
@@ -3319,7 +3389,7 @@ LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, LBPage *page, Commo
debug(3, "new LBLiveTextItem");
}
-void LBLiveTextItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream) {
+void LBLiveTextItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream) {
switch (type) {
case kLBLiveTextData:
{
@@ -3564,7 +3634,7 @@ LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common:
debug(3, "new LBPictureItem");
}
-void LBPictureItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream) {
+void LBPictureItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream) {
switch (type) {
case kLBSetDrawMode:
{
@@ -3790,8 +3860,8 @@ void LBProxyItem::init() {
}
debug(1, "LBProxyItem loading archive '%s' with id %d", filename.c_str(), baseId);
- MohawkArchive *pageArchive = _vm->createMohawkArchive();
- if (!pageArchive->open(filename))
+ Archive *pageArchive = _vm->createArchive();
+ if (!pageArchive->openFile(filename))
error("failed to open archive '%s' (for proxy '%s')", filename.c_str(), _desc.c_str());
_page = new LBPage(_vm);
_page->open(pageArchive, baseId);
diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h
index de84b0f13f..ed198a60c1 100644
--- a/engines/mohawk/livingbooks.h
+++ b/engines/mohawk/livingbooks.h
@@ -29,7 +29,6 @@
#include "mohawk/sound.h"
#include "common/config-file.h"
-#include "common/substream.h"
#include "common/rect.h"
#include "common/queue.h"
#include "common/random.h"
@@ -38,6 +37,11 @@
#include "livingbooks_code.h"
+namespace Common {
+ class SeekableSubReadStreamEndian;
+ class MemoryReadStreamEndian;
+}
+
namespace Mohawk {
#define LBKEY_MOD_CTRL 1
@@ -218,7 +222,7 @@ enum {
kLBOpBreakExpression = 0xfffc,
kLBOpJumpToExpression = 0xfffd,
kLBOpRunSubentries = 0xfffe,
- kLBOpRunCommand = 0xffff
+ kLBOpRunData = 0xffff
};
enum {
@@ -233,6 +237,12 @@ enum {
kLBNotifyQuit = 0xd
};
+enum {
+ kTargetTypeExpression = 0x3f3f,
+ kTargetTypeCode = 0xfffe,
+ kTargetTypeName = 0xffff
+};
+
class MohawkEngine_LivingBooks;
class LBPage;
class LBGraphics;
@@ -253,6 +263,9 @@ struct LBScriptEntry {
uint16 *argvParam;
uint16 *argvTarget;
+ uint16 targetingType;
+ Common::Array<Common::String> targets;
+
// kLBNotifyChangeMode
uint16 newUnknown;
uint16 newMode;
@@ -268,7 +281,10 @@ struct LBScriptEntry {
// kLBOpJumpUnlessExpression
uint16 target;
- Common::String command;
+ uint16 dataType;
+ uint16 dataLen;
+ byte *data;
+
Common::Array<Common::String> conditions;
Common::Array<LBScriptEntry *> subentries;
};
@@ -359,7 +375,8 @@ public:
virtual ~LBItem();
void readFrom(Common::SeekableSubReadStreamEndian *stream);
- virtual void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
+ void readData(uint16 type, uint16 size, byte *data);
+ virtual void readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream);
virtual void destroySelf(); // 0x2
virtual void setEnabled(bool enabled); // 0x3
@@ -421,7 +438,7 @@ protected:
void runCommand(const Common::String &command);
bool checkCondition(const Common::String &condition);
- LBScriptEntry *parseScriptEntry(uint16 type, uint16 &size, Common::SeekableSubReadStreamEndian *stream, bool isSubentry = false);
+ LBScriptEntry *parseScriptEntry(uint16 type, uint16 &size, Common::MemoryReadStreamEndian *stream, bool isSubentry = false);
};
class LBSoundItem : public LBItem {
@@ -446,7 +463,7 @@ class LBGroupItem : public LBItem {
public:
LBGroupItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
- void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
+ void readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream);
void destroySelf();
void setEnabled(bool enabled);
@@ -459,7 +476,7 @@ public:
void setGlobalVisible(bool visible);
void startPhase(uint phase);
void stop();
-
+
protected:
bool _starting;
@@ -471,7 +488,7 @@ public:
LBPaletteItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBPaletteItem();
- void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
+ void readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream);
bool togglePlaying(bool playing, bool restart);
void update();
@@ -497,7 +514,7 @@ class LBLiveTextItem : public LBItem {
public:
LBLiveTextItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
- void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
+ void readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream);
bool contains(Common::Point point);
void update();
@@ -526,7 +543,7 @@ class LBPictureItem : public LBItem {
public:
LBPictureItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
- void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
+ void readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *stream);
bool contains(Common::Point point);
void draw();
@@ -611,7 +628,7 @@ public:
LBPage(MohawkEngine_LivingBooks *vm);
~LBPage();
- void open(MohawkArchive *mhk, uint16 baseId);
+ void open(Archive *mhk, uint16 baseId);
uint16 getResourceVersion();
void itemDestroyed(LBItem *item);
@@ -621,7 +638,7 @@ public:
protected:
MohawkEngine_LivingBooks *_vm;
- MohawkArchive *_mhk;
+ Archive *_mhk;
Common::Array<LBItem *> _items;
uint16 _baseId;
@@ -646,12 +663,12 @@ public:
void addNotifyEvent(NotifyEvent event);
Common::SeekableSubReadStreamEndian *wrapStreamEndian(uint32 tag, uint16 id);
- Common::String readString(Common::SeekableSubReadStreamEndian *stream);
- Common::Rect readRect(Common::SeekableSubReadStreamEndian *stream);
+ Common::String readString(Common::ReadStream *stream);
+ Common::Rect readRect(Common::ReadStreamEndian *stream);
GUI::Debugger *getDebugger() { return _console; }
- void addArchive(MohawkArchive *archive);
- void removeArchive(MohawkArchive *Archive);
+ void addArchive(Archive *archive);
+ void removeArchive(Archive *Archive);
void addItem(LBItem *item);
void removeItems(const Common::Array<LBItem *> &items);
@@ -680,7 +697,7 @@ public:
// helper functions, also used by LBProxyItem
Common::String getFileNameFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover);
- MohawkArchive *createMohawkArchive() const;
+ Archive *createArchive() const;
private:
LivingBooksConsole *_console;
diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp
index 165ca4a328..e72318d86a 100644
--- a/engines/mohawk/livingbooks_code.cpp
+++ b/engines/mohawk/livingbooks_code.cpp
@@ -32,6 +32,10 @@ bool LBValue::operator==(const LBValue &x) const {
if (type != x.type) {
if (isNumeric() && x.isNumeric())
return toDouble() == x.toDouble();
+ else if (type == kLBValueString && x.type == kLBValueItemPtr)
+ return string == x.item->getName();
+ else if (type == kLBValueItemPtr && x.type == kLBValueString)
+ return item->getName() == x.string;
else
return false;
}
@@ -246,8 +250,10 @@ LBValue LBCode::runCode(byte terminator) {
parseStatement();
if (_stack.size())
result = _stack.pop();
- if (_currToken == terminator || _currToken == kTokenEndOfFile)
+ if (_currToken == terminator || _currToken == kTokenEndOfFile) {
+ debugN("\n");
break;
+ }
if (_currToken != kTokenEndOfStatement && _currToken != kTokenEndOfFile)
error("missing EOS (got %02x)", _currToken);
debugN("\n");
@@ -437,6 +443,33 @@ void LBCode::parseMain() {
}
break;
+ case kTokenPlusPlus:
+ case kTokenMinusMinus:
+ {
+ byte token = _currToken;
+ if (token == kTokenPlusPlus)
+ debugN("++");
+ else
+ debugN("--");
+ nextToken();
+
+ if (_currToken != kTokenIdentifier)
+ error("expected identifier");
+ assert(_currValue.type == kLBValueString);
+ Common::String varname = _currValue.string;
+ debugN("%s", varname.c_str());
+ LBValue &val = _vm->_variables[varname];
+
+ // FIXME: pre/postincrement for non-integers
+ if (token == kTokenPlusPlus)
+ val.integer++;
+ else
+ val.integer--;
+ _stack.push(val);
+ nextToken();
+ }
+ break;
+
case kTokenLiteral:
case kTokenConstMode:
case kTokenConstEventId:
diff --git a/engines/mohawk/mohawk.h b/engines/mohawk/mohawk.h
index b189f82040..2f0e570d56 100644
--- a/engines/mohawk/mohawk.h
+++ b/engines/mohawk/mohawk.h
@@ -28,6 +28,8 @@
#include "engines/engine.h"
+#include "mohawk/video.h"
+
class OSystem;
namespace Common {
@@ -75,8 +77,7 @@ enum MohawkGameFeatures {
struct MohawkGameDescription;
class Sound;
class PauseDialog;
-class MohawkArchive;
-class VideoManager;
+class Archive;
class CursorManager;
class MohawkEngine : public ::Engine {
@@ -112,13 +113,17 @@ public:
void pauseGame();
+ // Check if events should be done based on a video's current time
+ // (currently only used for Riven's storeMovieOpcode function)
+ virtual void doVideoTimer(VideoHandle handle, bool force) {}
+
private:
PauseDialog *_pauseDialog;
void pauseEngineIntern(bool);
protected:
// An array holding the main Mohawk archives require by the games
- Common::Array<MohawkArchive *> _mhk;
+ Common::Array<Archive *> _mhk;
};
} // End of namespace Mohawk
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index b60f8bd1ee..6bdf163a91 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -281,7 +281,7 @@ Common::Error MohawkEngine_Myst::run() {
// Load Help System (Masterpiece Edition Only)
if (getFeatures() & GF_ME) {
MohawkArchive *mhk = new MohawkArchive();
- if (!mhk->open("help.dat"))
+ if (!mhk->openFile("help.dat"))
error("Could not load help.dat");
_mhk.push_back(mhk);
}
@@ -488,7 +488,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
_mhk[0] = new MohawkArchive();
}
- if (!_mhk[0]->open(mystFiles[_curStack]))
+ if (!_mhk[0]->openFile(mystFiles[_curStack]))
error("Could not open %s", mystFiles[_curStack]);
if (getPlatform() == Common::kPlatformMacintosh)
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index be5b7e1c76..17f6de534f 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -436,89 +436,77 @@ void MystScriptParser::o_changeCardDirectional(uint16 op, uint16 var, uint16 arg
// but with the current cardId stored.
// Opcode 18 then "pops" this stored CardId and returns to that card.
-// TODO: The purpose of the optional argv[1] on Opcode 17 and argv[0]
-// on Opcode 18 which are always 4, 5 or 6 is unknown.
-
void MystScriptParser::o_changeCardPush(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- if (argc == 2) {
- debugC(kDebugScript, "Opcode %d: Jump to Card Id, Storing Current Card Id", op);
-
- uint16 cardId = argv[0];
- debugC(kDebugScript, "\tJump to CardId: %d", cardId);
+ debugC(kDebugScript, "Opcode %d: Jump to Card Id, Storing Current Card Id", op);
- uint16 u0 = argv[1]; // TODO
- debugC(kDebugScript, "\tu0: %d", u0);
+ _savedCardId = _vm->getCurCard();
+ uint16 cardId = argv[0];
- _savedCardId = _vm->getCurCard();
+ // argv[1] is not used in the original engine
- debugC(kDebugScript, "\tCurrent CardId: %d", _savedCardId);
+ debugC(kDebugScript, "\tCurrent CardId: %d", _savedCardId);
+ debugC(kDebugScript, "\tJump to CardId: %d", cardId);
- _vm->changeToCard(cardId, true);
- } else
- unknown(op, var, argc, argv);
+ _vm->changeToCard(cardId, true);
}
void MystScriptParser::o_changeCardPop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+ debugC(kDebugScript, "Opcode %d: Return To Stored Card Id", op);
+ debugC(kDebugScript, "\tCardId: %d", _savedCardId);
- if (argc == 1) {
- debugC(kDebugScript, "Opcode %d: Return To Stored Card Id", op);
- debugC(kDebugScript, "\tCardId: %d", _savedCardId);
+ // argv[0] is not used in the original engine
- uint16 u0 = argv[0];
- debugC(kDebugScript, "\tu0: %d", u0);
-
- _vm->changeToCard(_savedCardId, true);
- } else
- unknown(op, var, argc, argv);
+ _vm->changeToCard(_savedCardId, true);
}
void MystScriptParser::o_enableAreas(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+ debugC(kDebugScript, "Opcode %d: Enable Hotspots", op);
- if (argc > 0) {
- debugC(kDebugScript, "Opcode %d: Enable Hotspots", op);
+ uint16 count = argv[0];
- uint16 count = argv[0];
+ if (argc == count + 1) {
+ for (uint16 i = 0; i < count; i++) {
+ debugC(kDebugScript, "Enable hotspot index %d", argv[i + 1]);
- if (argc != count + 1)
- unknown(op, var, argc, argv);
- else {
- for (uint16 i = 0; i < count; i++) {
- debugC(kDebugScript, "Enable hotspot index %d", argv[i + 1]);
- _vm->setResourceEnabled(argv[i + 1], true);
- }
+ MystResource *resource = 0;
+ if (argv[i + 1] == 0xFFFF)
+ resource = _invokingResource;
+ else
+ resource = _vm->_resources[argv[i + 1]];
+
+ if (resource)
+ resource->setEnabled(true);
+ else
+ warning("Unknown Resource in enableAreas script Opcode");
}
- } else
- unknown(op, var, argc, argv);
+ } else {
+ error("Invalid arguments for opcode %d", op);
+ }
}
void MystScriptParser::o_disableAreas(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- if (argc > 0) {
- debugC(kDebugScript, "Opcode %d: Disable Hotspots", op);
-
- uint16 count = argv[0];
-
- if (argc != count + 1)
- unknown(op, var, argc, argv);
- else {
- for (uint16 i = 0; i < count; i++) {
- debugC(kDebugScript, "Disable hotspot index %d", argv[i + 1]);
- if (argv[i + 1] == 0xFFFF) {
- if (_invokingResource != NULL)
- _invokingResource->setEnabled(false);
- else
- warning("Unknown Resource in disableHotspots script Opcode");
- } else
- _vm->setResourceEnabled(argv[i + 1], false);
- }
+ debugC(kDebugScript, "Opcode %d: Disable Hotspots", op);
+
+ uint16 count = argv[0];
+
+ if (argc == count + 1) {
+ for (uint16 i = 0; i < count; i++) {
+ debugC(kDebugScript, "Disable hotspot index %d", argv[i + 1]);
+
+ MystResource *resource = 0;
+ if (argv[i + 1] == 0xFFFF)
+ resource = _invokingResource;
+ else
+ resource = _vm->_resources[argv[i + 1]];
+
+ if (resource)
+ resource->setEnabled(true);
+ else
+ warning("Unknown Resource in disableAreas script Opcode");
}
- } else
- unknown(op, var, argc, argv);
+ } else {
+ error("Invalid arguments for opcode %d", op);
+ }
}
void MystScriptParser::o_directionalUpdate(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -528,43 +516,37 @@ void MystScriptParser::o_directionalUpdate(uint16 op, uint16 var, uint16 argc, u
}
void MystScriptParser::o_toggleAreasActivation(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc > 0) {
- debugC(kDebugScript, "Opcode %d: Toggle areas activation", op);
+ debugC(kDebugScript, "Opcode %d: Toggle areas activation", op);
- uint16 count = argv[0];
+ uint16 count = argv[0];
- if (argc != count + 1)
- unknown(op, var, argc, argv);
- else {
- for (uint16 i = 0; i < count; i++) {
- debugC(kDebugScript, "Enable/Disable hotspot index %d", argv[i + 1]);
+ if (argc == count + 1) {
+ for (uint16 i = 0; i < count; i++) {
+ debugC(kDebugScript, "Enable/Disable hotspot index %d", argv[i + 1]);
- MystResource *resource = 0;
- if (argv[i + 1] == 0xFFFF)
- resource = _invokingResource;
- else
- resource = _vm->_resources[argv[i + 1]];
+ MystResource *resource = 0;
+ if (argv[i + 1] == 0xFFFF)
+ resource = _invokingResource;
+ else
+ resource = _vm->_resources[argv[i + 1]];
- if (resource)
- resource->setEnabled(!resource->isEnabled());
- }
+ if (resource)
+ resource->setEnabled(!resource->isEnabled());
+ else
+ warning("Unknown Resource in toggleAreasActivation script Opcode");
}
- } else
- unknown(op, var, argc, argv);
+ } else {
+ error("Invalid arguments for opcode %d", op);
+ }
}
void MystScriptParser::o_playSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- if (argc == 1) {
- uint16 soundId = argv[0];
+ uint16 soundId = argv[0];
- debugC(kDebugScript, "Opcode %d: playSound", op);
- debugC(kDebugScript, "\tsoundId: %d", soundId);
+ debugC(kDebugScript, "Opcode %d: playSound", op);
+ debugC(kDebugScript, "\tsoundId: %d", soundId);
- _vm->_sound->replaceSoundMyst(soundId);
- } else
- unknown(op, var, argc, argv);
+ _vm->_sound->replaceSoundMyst(soundId);
}
void MystScriptParser::o_stopSoundBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -590,7 +572,6 @@ void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, uint16 ar
// Used in Mechanical Card 6267 (Code Lock)
rect = _invokingResource->getRect();
} else {
- // Used in ... TODO: Fill in.
rect = Common::Rect(argv[0], argv[1], argv[2], argv[3]);
}
@@ -645,8 +626,6 @@ void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, uint16 arg
// by Channelwood Card 3280 (Tank Valve) and water flow sound behavior in pipe
// on cards leading from shed...
void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
int16 *soundList = NULL;
uint16 *soundListVolume = NULL;
@@ -709,7 +688,7 @@ void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, uint16 arg
warning("Unknown sound control value in opcode %d", op);
}
} else
- unknown(op, var, argc, argv);
+ warning("Unknown arg count in opcode %d", op);
delete[] soundList;
soundList = NULL;
@@ -783,25 +762,19 @@ void MystScriptParser::o_changeCard(uint16 op, uint16 var, uint16 argc, uint16 *
}
void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- if (argc == 3) {
debugC(kDebugScript, "Opcode %d: Draw Full Screen Image, Delay then Change Card", op);
uint16 imageId = argv[0];
uint16 cardId = argv[1];
- uint16 delay = argv[2]; // TODO: Not sure about argv[2] being delay..
+ // argv[2] is not used in the original engine
debugC(kDebugScript, "\timageId: %d", imageId);
debugC(kDebugScript, "\tcardId: %d", cardId);
- debugC(kDebugScript, "\tdelay: %d", delay);
_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
_vm->_system->updateScreen();
- _vm->_system->delayMillis(delay * 100);
+
_vm->changeToCard(cardId, true);
- } else
- unknown(op, var, argc, argv);
}
void MystScriptParser::o_changeMainCursor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -916,7 +889,8 @@ void MystScriptParser::o_soundWaitStop(uint16 op, uint16 var, uint16 argc, uint1
// Used when Button is pushed...
debugC(kDebugScript, "Opcode %d: Wait for foreground sound to finish", op);
- // TODO: Implement
+ while (_vm->_sound->isPlaying())
+ _vm->_system->delayMillis(10);
}
void MystScriptParser::o_quit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index 53d946dd66..5788f4b3a3 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -69,7 +69,7 @@ void Demo::disablePersistentScripts() {
void Demo::runPersistentScripts() {
Intro::runPersistentScripts();
-
+
if (_enabled201) {
// Used on Card 2001, 2002 and 2003
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 70abf0ccd3..66492d1200 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -397,7 +397,7 @@ uint16 Myst::getVar(uint16 var) {
else
return 0;
case 25: // Fireplace Red Page Present
- if (_globals.ending != 4)
+ if (_globals.ending != 4)
return !(_globals.redPagesInBook & 32) && (_globals.heldPage != 12);
else
return 0;
@@ -3269,7 +3269,7 @@ void Myst::generatorControlRoom_run(void) {
if (_generatorVoltage == _state.generatorVoltage) {
generatorRedrawRocket();
} else {
- // Animate generator gauge
+ // Animate generator gauge
if (_generatorVoltage > _state.generatorVoltage)
_generatorVoltage--;
else
diff --git a/engines/mohawk/resource.cpp b/engines/mohawk/resource.cpp
index 3a95b83199..9b39692958 100644
--- a/engines/mohawk/resource.cpp
+++ b/engines/mohawk/resource.cpp
@@ -29,23 +29,25 @@
namespace Mohawk {
-MohawkArchive::MohawkArchive() {
- _mhk = NULL;
- _types = NULL;
- _fileTable = NULL;
+// Base Archive code
+
+Archive::Archive() {
+ _stream = 0;
+}
+
+Archive::~Archive() {
+ close();
}
-bool MohawkArchive::open(const Common::String &filename) {
+bool Archive::openFile(const Common::String &fileName) {
Common::File *file = new Common::File();
- if (!file->open(filename)) {
+ if (!file->open(fileName)) {
delete file;
return false;
}
- _curFile = filename;
-
- if (!open(file)) {
+ if (!openStream(file)) {
close();
return false;
}
@@ -53,431 +55,371 @@ bool MohawkArchive::open(const Common::String &filename) {
return true;
}
-void MohawkArchive::close() {
- delete _mhk; _mhk = NULL;
- delete[] _types; _types = NULL;
- delete[] _fileTable; _fileTable = NULL;
-
- _curFile.clear();
+void Archive::close() {
+ _types.clear();
+ delete _stream; _stream = 0;
}
-bool MohawkArchive::open(Common::SeekableReadStream *stream) {
- // Make sure no other file is open...
- close();
- _mhk = stream;
-
- if (_mhk->readUint32BE() != ID_MHWK) {
- warning("Could not find tag 'MHWK'");
+bool Archive::hasResource(uint32 tag, uint16 id) const {
+ if (!_types.contains(tag))
return false;
- }
-
- /* uint32 fileSize = */ _mhk->readUint32BE();
- if (_mhk->readUint32BE() != ID_RSRC) {
- warning("Could not find tag \'RSRC\'");
- return false;
- }
+ return _types[tag].contains(id);
+}
- _rsrc.version = _mhk->readUint16BE();
-
- if (_rsrc.version != 0x100) {
- warning("Unsupported Mohawk resource version %d.%d", (_rsrc.version >> 8) & 0xff, _rsrc.version & 0xff);
+bool Archive::hasResource(uint32 tag, const Common::String &resName) const {
+ if (!_types.contains(tag) || resName.empty())
return false;
- }
-
- _rsrc.compaction = _mhk->readUint16BE(); // Only used in creation, not in reading
- _rsrc.filesize = _mhk->readUint32BE();
- _rsrc.abs_offset = _mhk->readUint32BE();
- _rsrc.file_table_offset = _mhk->readUint16BE();
- _rsrc.file_table_size = _mhk->readUint16BE();
- debug (3, "Absolute Offset = %08x", _rsrc.abs_offset);
+ const ResourceMap &resMap = _types[tag];
- /////////////////////////////////
- //Resource Dir
- /////////////////////////////////
+ for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++)
+ if (it->_value.name.matchString(resName))
+ return true;
- // Type Table
- _mhk->seek(_rsrc.abs_offset);
- _typeTable.name_offset = _mhk->readUint16BE();
- _typeTable.resource_types = _mhk->readUint16BE();
+ return false;
+}
- debug (0, "Name List Offset = %04x Number of Resource Types = %04x", _typeTable.name_offset, _typeTable.resource_types);
+Common::SeekableReadStream *Archive::getResource(uint32 tag, uint16 id) {
+ if (!_types.contains(tag))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
- _types = new Type[_typeTable.resource_types];
+ const ResourceMap &resMap = _types[tag];
- for (uint16 i = 0; i < _typeTable.resource_types; i++) {
- _types[i].tag = _mhk->readUint32BE();
- _types[i].resource_table_offset = _mhk->readUint16BE();
- _types[i].name_table_offset = _mhk->readUint16BE();
+ if (!resMap.contains(id))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
- // HACK: Zoombini's SND resource starts will a NULL.
- if (_types[i].tag == ID_SND)
- debug (3, "Type[%02d]: Tag = \'SND\' ResTable Offset = %04x NameTable Offset = %04x", i, _types[i].resource_table_offset, _types[i].name_table_offset);
- else
- debug (3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x NameTable Offset = %04x", i, tag2str(_types[i].tag), _types[i].resource_table_offset, _types[i].name_table_offset);
-
- // Resource Table
- _mhk->seek(_rsrc.abs_offset + _types[i].resource_table_offset);
- _types[i].resTable.resources = _mhk->readUint16BE();
+ const Resource &res = resMap[id];
- debug (3, "Resources = %04x", _types[i].resTable.resources);
+ return new Common::SeekableSubReadStream(_stream, res.offset, res.offset + res.size);
+}
- _types[i].resTable.entries = new Type::ResourceTable::Entries[_types[i].resTable.resources];
+uint32 Archive::getOffset(uint32 tag, uint16 id) const {
+ if (!_types.contains(tag))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
- for (uint16 j = 0; j < _types[i].resTable.resources; j++) {
- _types[i].resTable.entries[j].id = _mhk->readUint16BE();
- _types[i].resTable.entries[j].index = _mhk->readUint16BE();
+ const ResourceMap &resMap = _types[tag];
- debug (4, "Entry[%02x]: ID = %04x (%d) Index = %04x", j, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].index);
- }
+ if (!resMap.contains(id))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
- // Name Table
- _mhk->seek(_rsrc.abs_offset + _types[i].name_table_offset);
- _types[i].nameTable.num = _mhk->readUint16BE();
+ return resMap[id].offset;
+}
- debug (3, "Names = %04x", _types[i].nameTable.num);
+uint16 Archive::findResourceID(uint32 tag, const Common::String &resName) const {
+ if (!_types.contains(tag) || resName.empty())
+ return 0xFFFF;
- _types[i].nameTable.entries = new Type::NameTable::Entries[_types[i].nameTable.num];
+ const ResourceMap &resMap = _types[tag];
- for (uint16 j = 0; j < _types[i].nameTable.num; j++) {
- _types[i].nameTable.entries[j].offset = _mhk->readUint16BE();
- _types[i].nameTable.entries[j].index = _mhk->readUint16BE();
+ for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++)
+ if (it->_value.name.matchString(resName))
+ return it->_key;
- debug (4, "Entry[%02x]: Name List Offset = %04x Index = %04x", j, _types[i].nameTable.entries[j].offset, _types[i].nameTable.entries[j].index);
+ return 0xFFFF;
+}
- // Name List
- uint32 pos = _mhk->pos();
- _mhk->seek(_rsrc.abs_offset + _typeTable.name_offset + _types[i].nameTable.entries[j].offset);
- char c = (char)_mhk->readByte();
- while (c != 0) {
- _types[i].nameTable.entries[j].name += c;
- c = (char)_mhk->readByte();
- }
+Common::String Archive::getName(uint32 tag, uint16 id) const {
+ if (!_types.contains(tag))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
- debug (3, "Name = \'%s\'", _types[i].nameTable.entries[j].name.c_str());
+ const ResourceMap &resMap = _types[tag];
- // Get back to next entry
- _mhk->seek(pos);
- }
+ if (!resMap.contains(id))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
- // Return to next TypeTable entry
- _mhk->seek(_rsrc.abs_offset + (i + 1) * 8 + 4);
+ return resMap[id].name;
+}
- debug (3, "\n");
- }
+Common::Array<uint32> Archive::getResourceTypeList() const {
+ Common::Array<uint32> typeList;
- _mhk->seek(_rsrc.abs_offset + _rsrc.file_table_offset);
- _fileTableAmount = _mhk->readUint32BE();
- _fileTable = new FileTable[_fileTableAmount];
+ for (TypeMap::const_iterator it = _types.begin(); it != _types.end(); it++)
+ typeList.push_back(it->_key);
- for (uint32 i = 0; i < _fileTableAmount; i++) {
- _fileTable[i].offset = _mhk->readUint32BE();
- _fileTable[i].dataSize = _mhk->readUint16BE();
- _fileTable[i].dataSize += _mhk->readByte() << 16; // Get bits 15-24 of dataSize too
- _fileTable[i].flags = _mhk->readByte();
- _fileTable[i].unk = _mhk->readUint16BE();
+ return typeList;
+}
- // Add in another 3 bits for file size from the flags.
- // The flags are useless to us except for doing this ;)
- _fileTable[i].dataSize += (_fileTable[i].flags & 7) << 24;
+Common::Array<uint16> Archive::getResourceIDList(uint32 type) const {
+ Common::Array<uint16> idList;
- debug (4, "File[%02x]: Offset = %08x DataSize = %07x Flags = %02x Unk = %04x", i, _fileTable[i].offset, _fileTable[i].dataSize, _fileTable[i].flags, _fileTable[i].unk);
- }
+ if (!_types.contains(type))
+ return idList;
- return true;
-}
+ const ResourceMap &resMap = _types[type];
-int MohawkArchive::getTypeIndex(uint32 tag) {
- for (uint16 i = 0; i < _typeTable.resource_types; i++)
- if (_types[i].tag == tag)
- return i;
- return -1; // not found
-}
+ for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++)
+ idList.push_back(it->_key);
-int MohawkArchive::getIDIndex(int typeIndex, uint16 id) {
- for (uint16 i = 0; i < _types[typeIndex].resTable.resources; i++)
- if (_types[typeIndex].resTable.entries[i].id == id)
- return i;
- return -1; // not found
+ return idList;
}
-int MohawkArchive::getIDIndex(int typeIndex, const Common::String &resName) {
- int index = -1;
+// Mohawk Archive code
- for (uint16 i = 0; i < _types[typeIndex].nameTable.num; i++)
- if (_types[typeIndex].nameTable.entries[i].name.matchString(resName)) {
- index = _types[typeIndex].nameTable.entries[i].index;
- break;
- }
+struct FileTableEntry {
+ uint32 offset;
+ uint32 size;
+ byte flags;
+ uint16 unknown;
+};
- if (index < 0)
- return -1; // Not found
+struct NameTableEntry {
+ uint16 index;
+ Common::String name;
+};
- for (uint16 i = 0; i < _types[typeIndex].resTable.resources; i++)
- if (_types[typeIndex].resTable.entries[i].index == index)
- return i;
-
- return -1; // Not found
-}
-
-uint16 MohawkArchive::findResourceID(uint32 type, const Common::String &resName) {
- int typeIndex = getTypeIndex(type);
+bool MohawkArchive::openStream(Common::SeekableReadStream *stream) {
+ // Make sure no other file is open...
+ close();
- if (typeIndex < 0)
- return 0xFFFF;
+ if (stream->readUint32BE() != ID_MHWK) {
+ warning("Could not find tag 'MHWK'");
+ return false;
+ }
- int idIndex = getIDIndex(typeIndex, resName);
+ /* uint32 fileSize = */ stream->readUint32BE();
- if (idIndex < 0)
- return 0xFFFF;
+ if (stream->readUint32BE() != ID_RSRC) {
+ warning("Could not find tag \'RSRC\'");
+ return false;
+ }
- return _types[typeIndex].resTable.entries[idIndex].id;
-}
+ uint16 version = stream->readUint16BE();
-bool MohawkArchive::hasResource(uint32 tag, uint16 id) {
- if (!_mhk)
+ if (version != 0x100) {
+ warning("Unsupported Mohawk resource version %d.%d", (version >> 8) & 0xff, version & 0xff);
return false;
+ }
- int16 typeIndex = getTypeIndex(tag);
+ /* uint16 compaction = */ stream->readUint16BE(); // Only used in creation, not in reading
+ /* uint32 rsrcSize = */ stream->readUint32BE();
+ uint32 absOffset = stream->readUint32BE();
+ uint16 fileTableOffset = stream->readUint16BE();
+ /* uint16 fileTableSize = */ stream->readUint16BE();
- if (typeIndex < 0)
- return false;
+ // First, read in the file table
+ stream->seek(absOffset + fileTableOffset);
+ Common::Array<FileTableEntry> fileTable;
+ fileTable.resize(stream->readUint32BE());
- return getIDIndex(typeIndex, id) >= 0;
-}
+ debug(4, "Reading file table with %d entries", fileTable.size());
-bool MohawkArchive::hasResource(uint32 tag, const Common::String &resName) {
- if (!_mhk)
- return false;
+ for (uint32 i = 0; i < fileTable.size(); i++) {
+ fileTable[i].offset = stream->readUint32BE();
+ fileTable[i].size = stream->readUint16BE();
+ fileTable[i].size += stream->readByte() << 16; // Get bits 15-24 of size too
+ fileTable[i].flags = stream->readByte();
+ fileTable[i].unknown = stream->readUint16BE();
- int16 typeIndex = getTypeIndex(tag);
+ // Add in another 3 bits for file size from the flags.
+ // The flags are useless to us except for doing this ;)
+ fileTable[i].size += (fileTable[i].flags & 7) << 24;
- if (typeIndex < 0)
- return false;
+ debug(4, "File[%02x]: Offset = %08x Size = %07x Flags = %02x Unknown = %04x", i, fileTable[i].offset, fileTable[i].size, fileTable[i].flags, fileTable[i].unknown);
+ }
- return getIDIndex(typeIndex, resName) >= 0;
-}
+ // Now go in an read in each of the types
+ stream->seek(absOffset);
+ uint16 stringTableOffset = stream->readUint16BE();
+ uint16 typeCount = stream->readUint16BE();
-Common::String MohawkArchive::getName(uint32 tag, uint16 id) {
- if (!_mhk)
- return 0;
+ debug(0, "Name List Offset = %04x Number of Resource Types = %04x", stringTableOffset, typeCount);
- int16 typeIndex = getTypeIndex(tag);
+ for (uint16 i = 0; i < typeCount; i++) {
+ uint32 tag = stream->readUint32BE();
+ uint16 resourceTableOffset = stream->readUint16BE();
+ uint16 nameTableOffset = stream->readUint16BE();
- if (typeIndex < 0)
- return 0;
+ // HACK: Zoombini's SND resource starts will a NULL.
+ if (tag == ID_SND)
+ debug(3, "Type[%02d]: Tag = \'SND\' ResTable Offset = %04x NameTable Offset = %04x", i, resourceTableOffset, nameTableOffset);
+ else
+ debug(3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x NameTable Offset = %04x", i, tag2str(tag), resourceTableOffset, nameTableOffset);
- int16 idIndex = -1;
+ // Name Table
+ stream->seek(absOffset + nameTableOffset);
+ Common::Array<NameTableEntry> nameTable;
+ nameTable.resize(stream->readUint16BE());
- for (uint16 i = 0; i < _types[typeIndex].resTable.resources; i++)
- if (_types[typeIndex].resTable.entries[i].id == id) {
- idIndex = _types[typeIndex].resTable.entries[i].index;
- break;
- }
+ debug(3, "Names = %04x", nameTable.size());
- assert(idIndex >= 0);
+ for (uint16 j = 0; j < nameTable.size(); j++) {
+ uint16 offset = stream->readUint16BE();
+ nameTable[j].index = stream->readUint16BE();
- for (uint16 i = 0; i < _types[typeIndex].nameTable.num; i++)
- if (_types[typeIndex].nameTable.entries[i].index == idIndex)
- return _types[typeIndex].nameTable.entries[i].name;
+ debug(4, "Entry[%02x]: Name List Offset = %04x Index = %04x", j, offset, nameTable[j].index);
- return 0; // not found
-}
+ // Name List
+ uint32 pos = stream->pos();
+ stream->seek(absOffset + stringTableOffset + offset);
+ char c = (char)stream->readByte();
+ while (c != 0) {
+ nameTable[j].name += c;
+ c = (char)stream->readByte();
+ }
-uint32 MohawkArchive::getOffset(uint32 tag, uint16 id) {
- assert(_mhk);
+ debug(3, "Name = \'%s\'", nameTable[j].name.c_str());
- int16 typeIndex = getTypeIndex(tag);
- assert(typeIndex >= 0);
+ // Get back to next entry
+ stream->seek(pos);
+ }
- int16 idIndex = getIDIndex(typeIndex, id);
- assert(idIndex >= 0);
+ // Resource Table
+ stream->seek(absOffset + resourceTableOffset);
+ uint16 resourceCount = stream->readUint16BE();
- return _fileTable[_types[typeIndex].resTable.entries[idIndex].index - 1].offset;
-}
+ debug(3, "Resource count = %04x", resourceCount);
+
+ ResourceMap &resMap = _types[tag];
-Common::SeekableReadStream *MohawkArchive::getResource(uint32 tag, uint16 id) {
- if (!_mhk)
- error("MohawkArchive::getResource(): No File in Use");
+ for (uint16 j = 0; j < resourceCount; j++) {
+ uint16 id = stream->readUint16BE();
+ uint16 index = stream->readUint16BE();
- int16 typeIndex = getTypeIndex(tag);
+ Resource &res = resMap[id];
- if (typeIndex < 0)
- error("Could not find a tag of '%s' in file '%s'", tag2str(tag), _curFile.c_str());
+ // Pull out the name from the name table
+ for (uint32 k = 0; k < nameTable.size(); k++) {
+ if (nameTable[k].index == index) {
+ res.name = nameTable[k].name;
+ break;
+ }
+ }
- int16 idIndex = getIDIndex(typeIndex, id);
+ // Pull out our offset/size too
+ res.offset = fileTable[index - 1].offset;
+
+ // WORKAROUND: tMOV resources pretty much ignore the size part of the file table,
+ // as the original just passed the full Mohawk file to QuickTime and the offset.
+ // We need to do this because of the way Mohawk is set up (this is much more "proper"
+ // than passing _stream at the right offset). We may want to do that in the future, though.
+ if (tag == ID_TMOV) {
+ if (index == fileTable.size() - 1)
+ res.size = stream->size() - fileTable[index - 1].offset;
+ else
+ res.size = fileTable[index].offset - fileTable[index - 1].offset;
+ } else
+ res.size = fileTable[index - 1].size;
+
+ debug(4, "Entry[%02x]: ID = %04x (%d) Index = %04x", j, id, id, index);
+ }
- if (idIndex < 0)
- error("Could not find '%s' %04x in file '%s'", tag2str(tag), id, _curFile.c_str());
- // Note: the fileTableIndex is based off 1, not 0. So, subtract 1
- uint16 fileTableIndex = _types[typeIndex].resTable.entries[idIndex].index - 1;
+ // Return to next TypeTable entry
+ stream->seek(absOffset + (i + 1) * 8 + 4);
- // WORKAROUND: tMOV resources pretty much ignore the size part of the file table,
- // as the original just passed the full Mohawk file to QuickTime and the offset.
- // We need to do this because of the way Mohawk is set up (this is much more "proper"
- // than passing _mhk at the right offset). We may want to do that in the future, though.
- if (_types[typeIndex].tag == ID_TMOV) {
- if (fileTableIndex == _fileTableAmount - 1)
- return new Common::SeekableSubReadStream(_mhk, _fileTable[fileTableIndex].offset, _mhk->size());
- else
- return new Common::SeekableSubReadStream(_mhk, _fileTable[fileTableIndex].offset, _fileTable[fileTableIndex + 1].offset);
+ debug(3, "\n");
}
- return new Common::SeekableSubReadStream(_mhk, _fileTable[fileTableIndex].offset, _fileTable[fileTableIndex].offset + _fileTable[fileTableIndex].dataSize);
+ _stream = stream;
+ return true;
}
-bool LivingBooksArchive_v1::open(Common::SeekableReadStream *stream) {
+// Living Books Archive code
+
+bool LivingBooksArchive_v1::openStream(Common::SeekableReadStream *stream) {
close();
- _mhk = stream;
// This is for the "old" Mohawk resource format used in some older
// Living Books. It is very similar, just missing the MHWK tag and
// some other minor differences, especially with the file table
// being merged into the resource table.
- uint32 headerSize = _mhk->readUint32BE();
+ uint32 headerSize = stream->readUint32BE();
// NOTE: There are differences besides endianness! (Subtle changes,
// but different).
if (headerSize == 6) { // We're in Big Endian mode (Macintosh)
- _mhk->readUint16BE(); // Resource Table Size
- _typeTable.resource_types = _mhk->readUint16BE();
- _types = new OldType[_typeTable.resource_types];
+ stream->readUint16BE(); // Resource Table Size
+ uint16 typeCount = stream->readUint16BE();
- debug (0, "Old Mohawk File (Macintosh): Number of Resource Types = %04x", _typeTable.resource_types);
+ debug(0, "Old Mohawk File (Macintosh): Number of Resource Types = %04x", typeCount);
- for (uint16 i = 0; i < _typeTable.resource_types; i++) {
- _types[i].tag = _mhk->readUint32BE();
- _types[i].resource_table_offset = (uint16)_mhk->readUint32BE() + 6;
- _mhk->readUint32BE(); // Unknown (always 0?)
+ for (uint16 i = 0; i < typeCount; i++) {
+ uint32 tag = stream->readUint32BE();
+ uint32 resourceTableOffset = stream->readUint32BE() + 6;
+ stream->readUint32BE(); // Unknown (always 0?)
- debug (3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x", i, tag2str(_types[i].tag), _types[i].resource_table_offset);
+ debug(3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x", i, tag2str(tag), resourceTableOffset);
- uint32 oldPos = _mhk->pos();
+ uint32 oldPos = stream->pos();
// Resource Table/File Table
- _mhk->seek(_types[i].resource_table_offset);
- _types[i].resTable.resources = _mhk->readUint16BE();
- _types[i].resTable.entries = new OldType::ResourceTable::Entries[_types[i].resTable.resources];
-
- for (uint16 j = 0; j < _types[i].resTable.resources; j++) {
- _types[i].resTable.entries[j].id = _mhk->readUint16BE();
- _types[i].resTable.entries[j].offset = _mhk->readUint32BE();
- _types[i].resTable.entries[j].size = _mhk->readByte() << 16;
- _types[i].resTable.entries[j].size += _mhk->readUint16BE();
- _mhk->skip(5); // Unknown (always 0?)
-
- debug (4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].offset, _types[i].resTable.entries[j].size);
- }
+ stream->seek(resourceTableOffset);
+ uint16 resourceCount = stream->readUint16BE();
- _mhk->seek(oldPos);
- debug (3, "\n");
- }
- } else if (SWAP_BYTES_32(headerSize) == 6) { // We're in Little Endian mode (Windows)
- _mhk->readUint16LE(); // Resource Table Size
- _typeTable.resource_types = _mhk->readUint16LE();
- _types = new OldType[_typeTable.resource_types];
-
- debug (0, "Old Mohawk File (Windows): Number of Resource Types = %04x", _typeTable.resource_types);
-
- for (uint16 i = 0; i < _typeTable.resource_types; i++) {
- _types[i].tag = _mhk->readUint32LE();
- _types[i].resource_table_offset = _mhk->readUint16LE() + 6;
- _mhk->readUint16LE(); // Unknown (always 0?)
+ ResourceMap &resMap = _types[tag];
- debug (3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x", i, tag2str(_types[i].tag), _types[i].resource_table_offset);
+ for (uint16 j = 0; j < resourceCount; j++) {
+ uint16 id = stream->readUint16BE();
- uint32 oldPos = _mhk->pos();
+ Resource &res = resMap[id];
- // Resource Table/File Table
- _mhk->seek(_types[i].resource_table_offset);
- _types[i].resTable.resources = _mhk->readUint16LE();
- _types[i].resTable.entries = new OldType::ResourceTable::Entries[_types[i].resTable.resources];
-
- for (uint16 j = 0; j < _types[i].resTable.resources; j++) {
- _types[i].resTable.entries[j].id = _mhk->readUint16LE();
- _types[i].resTable.entries[j].offset = _mhk->readUint32LE();
- _types[i].resTable.entries[j].size = _mhk->readUint32LE();
- _mhk->readUint16LE(); // Unknown (always 0?)
+ res.offset = stream->readUint32BE();
+ res.size = stream->readByte() << 16;
+ res.size |= stream->readUint16BE();
+ stream->skip(5); // Unknown (always 0?)
- debug (4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].offset, _types[i].resTable.entries[j].size);
+ debug(4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, id, id, res.offset, res.size);
}
- _mhk->seek(oldPos);
- debug (3, "\n");
+ stream->seek(oldPos);
+ debug(3, "\n");
}
- } else {
- warning("Could not determine type of Old Mohawk resource");
- return false;
- }
-
- return true;
-}
-
-uint32 LivingBooksArchive_v1::getOffset(uint32 tag, uint16 id) {
- assert(_mhk);
+ } else if (SWAP_BYTES_32(headerSize) == 6) { // We're in Little Endian mode (Windows)
+ stream->readUint16LE(); // Resource Table Size
+ uint16 typeCount = stream->readUint16LE();
- int16 typeIndex = getTypeIndex(tag);
- assert(typeIndex >= 0);
+ debug(0, "Old Mohawk File (Windows): Number of Resource Types = %04x", typeCount);
- int16 idIndex = getIDIndex(typeIndex, id);
- assert(idIndex >= 0);
+ for (uint16 i = 0; i < typeCount; i++) {
+ uint32 tag = stream->readUint32LE();
+ uint16 resourceTableOffset = stream->readUint16LE() + 6;
+ stream->readUint16LE(); // Unknown (always 0?)
- return _types[typeIndex].resTable.entries[idIndex].offset;
-}
+ debug(3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x", i, tag2str(tag), resourceTableOffset);
-Common::SeekableReadStream *LivingBooksArchive_v1::getResource(uint32 tag, uint16 id) {
- if (!_mhk)
- error("LivingBooksArchive_v1::getResource(): No File in Use");
+ uint32 oldPos = stream->pos();
- int16 typeIndex = getTypeIndex(tag);
-
- if (typeIndex < 0)
- error("Could not find a tag of \'%s\' in file \'%s\'", tag2str(tag), _curFile.c_str());
+ // Resource Table/File Table
+ stream->seek(resourceTableOffset);
+ uint16 resourceCount = stream->readUint16LE();
- int16 idIndex = getIDIndex(typeIndex, id);
+ ResourceMap &resMap = _types[tag];
- if (idIndex < 0)
- error("Could not find \'%s\' %04x in file \'%s\'", tag2str(tag), id, _curFile.c_str());
+ for (uint16 j = 0; j < resourceCount; j++) {
+ uint16 id = stream->readUint16LE();
- return new Common::SeekableSubReadStream(_mhk, _types[typeIndex].resTable.entries[idIndex].offset, _types[typeIndex].resTable.entries[idIndex].offset + _types[typeIndex].resTable.entries[idIndex].size);
-}
+ Resource &res = resMap[id];
-bool LivingBooksArchive_v1::hasResource(uint32 tag, uint16 id) {
- if (!_mhk)
- return false;
+ res.offset = stream->readUint32LE();
+ res.size = stream->readUint32LE();
+ stream->readUint16LE(); // Unknown (always 0?)
- int16 typeIndex = getTypeIndex(tag);
+ debug(4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, id, id, res.offset, res.size);
+ }
- if (typeIndex < 0)
+ stream->seek(oldPos);
+ debug(3, "\n");
+ }
+ } else {
+ // Not a valid Living Books Archive
return false;
+ }
- return getIDIndex(typeIndex, id) >= 0;
+ _stream = stream;
+ return true;
}
-int LivingBooksArchive_v1::getTypeIndex(uint32 tag) {
- for (uint16 i = 0; i < _typeTable.resource_types; i++)
- if (_types[i].tag == tag)
- return i;
- return -1; // not found
-}
-
-int LivingBooksArchive_v1::getIDIndex(int typeIndex, uint16 id) {
- for (uint16 i = 0; i < _types[typeIndex].resTable.resources; i++)
- if (_types[typeIndex].resTable.entries[i].id == id)
- return i;
- return -1; // not found
-}
+// DOS Archive (v2) code
// Partially based on the Prince of Persia Format Specifications
// See http://sdfg.com.ar/git/?p=fp-git.git;a=blob;f=FP/doc/FormatSpecifications
// However, I'm keeping with the terminology we've been using with the
// later archive formats.
-bool DOSArchive_v2::open(Common::SeekableReadStream *stream) {
+bool DOSArchive_v2::openStream(Common::SeekableReadStream *stream) {
close();
uint32 typeTableOffset = stream->readUint32LE();
@@ -488,36 +430,38 @@ bool DOSArchive_v2::open(Common::SeekableReadStream *stream) {
stream->seek(typeTableOffset);
- _typeTable.resource_types = stream->readUint16LE();
- _types = new OldType[_typeTable.resource_types];
+ uint16 typeCount = stream->readUint16LE();
- for (uint16 i = 0; i < _typeTable.resource_types; i++) {
- _types[i].tag = stream->readUint32LE();
- _types[i].resource_table_offset = stream->readUint16LE();
+ for (uint16 i = 0; i < typeCount; i++) {
+ uint32 tag = stream->readUint32LE();
+ uint16 resourceTableOffset = stream->readUint16LE();
- debug(3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x", i, tag2str(_types[i].tag), _types[i].resource_table_offset);
+ debug(3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x", i, tag2str(tag), resourceTableOffset);
uint32 oldPos = stream->pos();
// Resource Table/File Table
- stream->seek(_types[i].resource_table_offset + typeTableOffset);
- _types[i].resTable.resources = stream->readUint16LE();
- _types[i].resTable.entries = new OldType::ResourceTable::Entries[_types[i].resTable.resources];
+ stream->seek(resourceTableOffset + typeTableOffset);
+ uint16 resourceCount = stream->readUint16LE();
+
+ ResourceMap &resMap = _types[tag];
+
+ for (uint16 j = 0; j < resourceCount; j++) {
+ uint16 id = stream->readUint16LE();
- for (uint16 j = 0; j < _types[i].resTable.resources; j++) {
- _types[i].resTable.entries[j].id = stream->readUint16LE();
- _types[i].resTable.entries[j].offset = stream->readUint32LE() + 1; // Need to add one to the offset to skip the checksum byte
- _types[i].resTable.entries[j].size = stream->readUint16LE();
- stream->skip(3); // Skip the useless flags
+ Resource &res = resMap[id];
+ res.offset = stream->readUint32LE() + 1; // Need to add one to the offset to skip the checksum byte
+ res.size = stream->readUint16LE();
+ stream->skip(3); // Skip (useless) flags
- debug (4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].offset, _types[i].resTable.entries[j].size);
+ debug(4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, id, id, res.offset, res.size);
}
stream->seek(oldPos);
- debug (3, "\n");
+ debug(3, "\n");
}
- _mhk = stream;
+ _stream = stream;
return true;
}
diff --git a/engines/mohawk/resource.h b/engines/mohawk/resource.h
index cabce04e38..f2ead7af65 100644
--- a/engines/mohawk/resource.h
+++ b/engines/mohawk/resource.h
@@ -22,6 +22,7 @@
#include "common/scummsys.h"
#include "common/endian.h"
+#include "common/hashmap.h"
#include "common/file.h"
#include "common/str.h"
@@ -128,127 +129,64 @@ namespace Mohawk {
#define ID_BBOX MKTAG('B','B','O','X') // Boxes? (CSWorld, CSAmtrak)
#define ID_SYSX MKTAG('S','Y','S','X') // MIDI Sysex
-struct FileTable {
- uint32 offset;
- uint32 dataSize; // Really 27 bits
- byte flags; // Mostly useless except for the bottom 3 bits which are part of the size
- uint16 unk; // Always 0
-};
-
-struct Type {
- Type() { resTable.entries = NULL; nameTable.entries = NULL; }
- ~Type() { delete[] resTable.entries; delete[] nameTable.entries; }
-
- //Type Table
- uint32 tag;
- uint16 resource_table_offset;
- uint16 name_table_offset;
-
- struct ResourceTable {
- uint16 resources;
- struct Entries {
- uint16 id;
- uint16 index;
- } *entries;
- } resTable;
-
- struct NameTable {
- uint16 num;
- struct Entries {
- uint16 offset;
- uint16 index;
- // Name List
- Common::String name;
- } *entries;
- } nameTable;
-};
-
-struct TypeTable {
- uint16 name_offset;
- uint16 resource_types;
-};
-struct RSRC_Header {
- uint16 version;
- uint16 compaction;
- uint32 filesize;
- uint32 abs_offset;
- uint16 file_table_offset;
- uint16 file_table_size;
-};
-
-class MohawkArchive {
+class Archive {
public:
- MohawkArchive();
- virtual ~MohawkArchive() { close(); }
+ Archive();
+ virtual ~Archive();
- bool open(const Common::String &filename);
- virtual bool open(Common::SeekableReadStream *stream);
+ bool openFile(const Common::String &fileName);
+ virtual bool openStream(Common::SeekableReadStream *stream) = 0;
void close();
- virtual bool hasResource(uint32 tag, uint16 id);
- virtual bool hasResource(uint32 tag, const Common::String &resName);
- virtual Common::SeekableReadStream *getResource(uint32 tag, uint16 id);
- virtual uint32 getOffset(uint32 tag, uint16 id);
- virtual uint16 findResourceID(uint32 type, const Common::String &resName);
- Common::String getName(uint32 tag, uint16 id);
+ bool isOpen() const { return _stream != 0; }
+
+ bool hasResource(uint32 tag, uint16 id) const;
+ bool hasResource(uint32 tag, const Common::String &resName) const;
+ Common::SeekableReadStream *getResource(uint32 tag, uint16 id);
+ uint32 getOffset(uint32 tag, uint16 id) const;
+ uint16 findResourceID(uint32 tag, const Common::String &resName) const;
+ Common::String getName(uint32 tag, uint16 id) const;
+
+ Common::Array<uint32> getResourceTypeList() const;
+ Common::Array<uint16> getResourceIDList(uint32 type) const;
protected:
- Common::SeekableReadStream *_mhk;
- TypeTable _typeTable;
- Common::String _curFile;
-
-private:
- RSRC_Header _rsrc;
- Type *_types;
- FileTable *_fileTable;
- uint16 _nameTableAmount;
- uint16 _resourceTableAmount;
- uint16 _fileTableAmount;
-
- int getTypeIndex(uint32 tag);
- int getIDIndex(int typeIndex, uint16 id);
- int getIDIndex(int typeIndex, const Common::String &resName);
+ Common::SeekableReadStream *_stream;
+
+ struct Resource {
+ uint32 offset;
+ uint32 size;
+ Common::String name;
+ };
+
+ typedef Common::HashMap<uint16, Resource> ResourceMap;
+ typedef Common::HashMap<uint32, ResourceMap> TypeMap;
+ TypeMap _types;
};
-class LivingBooksArchive_v1 : public MohawkArchive {
+class MohawkArchive : public Archive {
public:
- LivingBooksArchive_v1() : MohawkArchive() {}
- ~LivingBooksArchive_v1() {}
+ MohawkArchive() : Archive() {}
+ ~MohawkArchive() {}
- bool hasResource(uint32 tag, uint16 id);
- bool hasResource(uint32 tag, const Common::String &resName) { return false; }
- virtual bool open(Common::SeekableReadStream *stream);
- Common::SeekableReadStream *getResource(uint32 tag, uint16 id);
- Common::SeekableReadStream *getResource(uint32 tag, const Common::String &resName) { return 0; }
- uint32 getOffset(uint32 tag, uint16 id);
- uint16 findResourceID(uint32 type, const Common::String &resName) { return 0xFFFF; }
+ bool openStream(Common::SeekableReadStream *stream);
+};
-protected:
- struct OldType {
- uint32 tag;
- uint16 resource_table_offset;
- struct ResourceTable {
- uint16 resources;
- struct Entries {
- uint16 id;
- uint32 offset;
- uint32 size;
- } *entries;
- } resTable;
- } *_types;
-
-private:
- int getTypeIndex(uint32 tag);
- int getIDIndex(int typeIndex, uint16 id);
+class LivingBooksArchive_v1 : public Archive {
+public:
+ LivingBooksArchive_v1() : Archive() {}
+ ~LivingBooksArchive_v1() {}
+
+ bool openStream(Common::SeekableReadStream *stream);
};
-class DOSArchive_v2 : public LivingBooksArchive_v1 {
+class DOSArchive_v2 : public Archive {
public:
- DOSArchive_v2() : LivingBooksArchive_v1() {}
+ DOSArchive_v2() : Archive() {}
~DOSArchive_v2() {}
- virtual bool open(Common::SeekableReadStream *stream);
+ bool openStream(Common::SeekableReadStream *stream);
};
} // End of namespace Mohawk
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 57a0ac717d..612b8b3685 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -143,7 +143,7 @@ Common::Error MohawkEngine_Riven::run() {
_extrasFile = new MohawkArchive();
// We need extras.mhk for inventory images, marble images, and credits images
- if (!_extrasFile->open("extras.mhk")) {
+ if (!_extrasFile->openFile("extras.mhk")) {
Common::String message = "You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also works.";
GUIErrorMessage(message);
warning("%s", message.c_str());
@@ -178,7 +178,7 @@ Common::Error MohawkEngine_Riven::run() {
changeToCard(1);
}
-
+
while (!_gameOver && !shouldQuit())
handleEvents();
@@ -317,7 +317,7 @@ void MohawkEngine_Riven::changeToStack(uint16 n) {
Common::String filename = Common::String(prefix) + endings[i];
MohawkArchive *mhk = new MohawkArchive();
- if (mhk->open(filename))
+ if (mhk->openFile(filename))
_mhk.push_back(mhk);
else
delete mhk;
@@ -436,7 +436,7 @@ void MohawkEngine_Riven::loadCard(uint16 id) {
void MohawkEngine_Riven::loadHotspots(uint16 id) {
// Clear old hotspots
delete[] _hotspots;
-
+
// NOTE: The hotspot scripts are cleared by the RivenScriptManager automatically.
Common::SeekableReadStream *inStream = getResource(ID_HSPT, id);
@@ -460,8 +460,8 @@ void MohawkEngine_Riven::loadHotspots(uint16 id) {
// - tspit 371 (DVD: 377), hotspot 4
if (left >= right || top >= bottom) {
warning("%s %d hotspot %d is invalid: (%d, %d, %d, %d)", getStackName(_curStack).c_str(), _curCard, i, left, top, right, bottom);
- left = top = right = bottom = 0;
- _hotspots[i].enabled = 0;
+ left = top = right = bottom = 0;
+ _hotspots[i].enabled = 0;
}
_hotspots[i].rect = Common::Rect(left, top, right, bottom);
@@ -833,6 +833,19 @@ void MohawkEngine_Riven::installCardTimer() {
}
}
+void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) {
+ assert(handle != NULL_VID_HANDLE);
+
+ uint16 id = _scriptMan->getStoredMovieOpcodeID();
+
+ if (handle != _video->findVideoHandleRiven(id)) // Check if we've got a video match
+ return;
+
+ // Run the opcode if we can at this point
+ if (force || _video->getElapsedTime(handle) >= _scriptMan->getStoredMovieOpcodeTime())
+ _scriptMan->runStoredMovieOpcode();
+}
+
bool ZipMode::operator== (const ZipMode &z) const {
return z.name == name && z.id == id;
}
diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h
index c80f497e37..c7d36e585d 100644
--- a/engines/mohawk/riven.h
+++ b/engines/mohawk/riven.h
@@ -131,6 +131,8 @@ public:
typedef void (*TimerProc)(MohawkEngine_Riven *vm);
+ void doVideoTimer(VideoHandle handle, bool force);
+
private:
MohawkArchive *_extrasFile; // We need a separate handle for the extra data
RivenConsole *_console;
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 8ad05ded13..60e94ea795 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -244,7 +244,7 @@ void RivenExternal::runCredits(uint16 video, uint32 delay) {
_vm->_gfx->updateCredits();
}
} else if (_vm->_video->updateMovies())
- _vm->_system->updateScreen();
+ _vm->_system->updateScreen();
Common::Event event;
while (_vm->_system->getEventManager()->pollEvent(event))
@@ -2060,7 +2060,7 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
_vm->_cursor->setCursor(kRivenMainCursor);
_vm->_system->updateScreen();
-
+
// OK, Gehn has opened the trap book and has asked us to go in. Let's watch
// and see what the player will do...
while (_vm->_video->getElapsedTime(video) < endTime && !_vm->shouldQuit()) {
@@ -2216,7 +2216,7 @@ void RivenExternal::xgwatch(uint16 argc, uint16 *argv) {
curSound++;
soundTime = _vm->_system->getMillis();
}
-
+
// Poll events just to check for quitting
Common::Event event;
while (_vm->_system->getEventManager()->pollEvent(event)) {}
@@ -2525,7 +2525,7 @@ static Common::Rect generateMarbleGridRect(uint16 x, uint16 y) {
}
void RivenExternal::xt7500_checkmarbles(uint16 argc, uint16 *argv) {
- // Set apower if the marbles are in their correct spot.
+ // Set apower if the marbles are in their correct spot.
bool valid = true;
static const uint32 marbleFinalValues[] = { 1114121, 1441798, 0, 65552, 65558, 262146 };
diff --git a/engines/mohawk/riven_saveload.cpp b/engines/mohawk/riven_saveload.cpp
index 35d82d4aa0..18c13ec12b 100644
--- a/engines/mohawk/riven_saveload.cpp
+++ b/engines/mohawk/riven_saveload.cpp
@@ -100,7 +100,7 @@ bool RivenSaveLoad::loadGame(Common::String filename) {
MohawkArchive *mhk = new MohawkArchive();
- if (!mhk->open(loadFile)) {
+ if (!mhk->openStream(loadFile)) {
warning("Save file is not a Mohawk archive");
delete mhk;
return false;
@@ -274,7 +274,16 @@ Common::MemoryWriteStreamDynamic *RivenSaveLoad::genZIPSSection() {
}
bool RivenSaveLoad::saveGame(Common::String filename) {
- // Note, this code is still WIP. It works quite well for now.
+ // NOTE: This code is designed to only output a Mohawk archive
+ // for a Riven saved game. It's hardcoded to do this because
+ // (as of right now) this is the only place in the engine
+ // that requires this feature. If the time comes when other
+ // games need this, we should think about coming up with some
+ // more common way of outputting resources to an archive.
+
+ // TODO: Make these saves work with the original interpreter.
+ // Not sure why they don't work yet (they still can be loaded
+ // by ScummVM).
// Make sure we have the right extension
if (!filename.matchString("*.rvn", true))
@@ -296,99 +305,101 @@ bool RivenSaveLoad::saveGame(Common::String filename) {
Common::MemoryWriteStreamDynamic *zipsSection = genZIPSSection();
// Let's calculate the file size!
- uint32 fileSize = 0;
+ uint32 fileSize = 142;
fileSize += versSection->size();
fileSize += nameSection->size();
fileSize += varsSection->size();
fileSize += zipsSection->size();
- fileSize += 16; // RSRC Header
- fileSize += 4; // Type Table Header
- fileSize += 4 * 8; // Type Table Entries
- fileSize += 2; // Pseudo-Name entries
- // IFF Header
+ // MHWK Header (8 bytes - total: 8)
saveFile->writeUint32BE(ID_MHWK);
- saveFile->writeUint32BE(fileSize);
+ saveFile->writeUint32BE(fileSize - 8);
- // RSRC Header
+ // RSRC Header (20 bytes - total: 28)
saveFile->writeUint32BE(ID_RSRC);
saveFile->writeUint16BE(0x100); // Resource Version (1.0)
- saveFile->writeUint16BE(0); // No compaction
- saveFile->writeUint32BE(fileSize + 8); // Add on the 8 from the IFF header
- saveFile->writeUint32BE(28); // IFF + RSRC
- saveFile->writeUint16BE(62); // File Table Offset
- saveFile->writeUint16BE(44); // 4 + 4 * 10
-
- //Type Table
- saveFile->writeUint16BE(36); // After the Type Table Entries
+ saveFile->writeUint16BE(1); // Compaction -- original saves have this too
+ saveFile->writeUint32BE(fileSize); // Subtract off the MHWK header size
+ saveFile->writeUint32BE(28); // Absolute offset: right after both headers
+ saveFile->writeUint16BE(70); // File Table Offset
+ saveFile->writeUint16BE(44); // File Table Size (4 bytes count + 4 entries * 10 bytes per entry)
+
+ // Type Table (4 bytes - total: 32)
+ saveFile->writeUint16BE(36); // String table offset After the Type Table Entries
saveFile->writeUint16BE(4); // 4 Type Table Entries
- // Hardcode Entries
+ // Hardcode Entries (32 bytes - total: 64)
saveFile->writeUint32BE(ID_VERS);
- saveFile->writeUint16BE(38);
- saveFile->writeUint16BE(36);
+ saveFile->writeUint16BE(46); // Resource table offset
+ saveFile->writeUint16BE(38); // String table offset
saveFile->writeUint32BE(ID_NAME);
- saveFile->writeUint16BE(44);
- saveFile->writeUint16BE(36);
+ saveFile->writeUint16BE(52);
+ saveFile->writeUint16BE(40);
saveFile->writeUint32BE(ID_VARS);
- saveFile->writeUint16BE(50);
- saveFile->writeUint16BE(36);
+ saveFile->writeUint16BE(58);
+ saveFile->writeUint16BE(42);
saveFile->writeUint32BE(ID_ZIPS);
- saveFile->writeUint16BE(56);
- saveFile->writeUint16BE(36);
+ saveFile->writeUint16BE(64);
+ saveFile->writeUint16BE(44);
- // Pseudo-Name Table/Name List
+ // Pseudo-String Table (2 bytes - total: 66)
saveFile->writeUint16BE(0); // We don't need a name list
- // VERS Section (Resource Table)
+ // Psuedo-Name Tables (8 bytes - total: 74)
+ saveFile->writeUint16BE(0);
+ saveFile->writeUint16BE(0);
+ saveFile->writeUint16BE(0);
+ saveFile->writeUint16BE(0);
+
+ // VERS Section (Resource Table) (6 bytes - total: 80)
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(1);
- // NAME Section (Resource Table)
+ // NAME Section (Resource Table) (6 bytes - total: 86)
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(2);
- // VARS Section (Resource Table)
+ // VARS Section (Resource Table) (6 bytes - total: 92)
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(3);
- // ZIPS Section (Resource Table)
+ // ZIPS Section (Resource Table) (6 bytes - total: 98)
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(1);
saveFile->writeUint16BE(4);
- // File Table
+ // File Table (4 bytes - total: 102)
saveFile->writeUint32BE(4);
- // VERS Section (File Table)
- saveFile->writeUint32BE(134);
+ // VERS Section (File Table) (10 bytes - total: 112)
+ saveFile->writeUint32BE(142);
saveFile->writeUint16BE(versSection->size() & 0xFFFF);
saveFile->writeByte((versSection->size() & 0xFF0000) >> 16);
saveFile->writeByte(0);
saveFile->writeUint16BE(0);
- // NAME Section (File Table)
- saveFile->writeUint32BE(134 + versSection->size());
+ // NAME Section (File Table) (10 bytes - total: 122)
+ saveFile->writeUint32BE(142 + versSection->size());
saveFile->writeUint16BE(nameSection->size() & 0xFFFF);
saveFile->writeByte((nameSection->size() & 0xFF0000) >> 16);
saveFile->writeByte(0);
saveFile->writeUint16BE(0);
- // VARS Section (File Table)
- saveFile->writeUint32BE(134 + versSection->size() + nameSection->size());
+ // VARS Section (File Table) (10 bytes - total: 132)
+ saveFile->writeUint32BE(142 + versSection->size() + nameSection->size());
saveFile->writeUint16BE(varsSection->size() & 0xFFFF);
saveFile->writeByte((varsSection->size() & 0xFF0000) >> 16);
saveFile->writeByte(0);
saveFile->writeUint16BE(0);
- // ZIPS Section (File Table)
- saveFile->writeUint32BE(134 + versSection->size() + nameSection->size() + varsSection->size());
+ // ZIPS Section (File Table) (10 bytes - total: 142)
+ saveFile->writeUint32BE(142 + versSection->size() + nameSection->size() + varsSection->size());
saveFile->writeUint16BE(zipsSection->size() & 0xFFFF);
saveFile->writeByte((zipsSection->size() & 0xFF0000) >> 16);
saveFile->writeByte(0);
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index b3d5369a84..6e3e9a34dc 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -407,14 +407,14 @@ void RivenScript::stopSound(uint16 op, uint16 argc, uint16 *argv) {
return;
// The argument is a bitflag for the setting.
- // bit 0 is normal sound stopping (unused)
+ // bit 0 is normal sound stopping
// bit 1 is ambient sound stopping
// Having no flags set means clear all
if (argv[0] & 2 || argv[0] == 0)
_vm->_sound->stopAllSLST();
- if (argv[0] & 1)
- warning("Unhandled stopSound() flag");
+ if (argv[0] & 1 || argv[0] == 0)
+ _vm->_sound->stopSound();
}
// Command 13: set mouse cursor (cursor_id)
@@ -536,13 +536,17 @@ void RivenScript::fadeAmbientSounds(uint16 op, uint16 argc, uint16 *argv) {
// Command 38: Store an opcode for use when playing a movie (movie id, time high, time low, opcode, arguments...)
void RivenScript::storeMovieOpcode(uint16 op, uint16 argc, uint16 *argv) {
+ // This opcode is used to delay an opcode's usage based on the elapsed
+ // time of a specified movie. However, every use in the game is for
+ // delaying an activateSLST opcode.
+
uint32 scriptSize = 6 + (argc - 4) * 2;
// Create our dummy script
byte *scriptBuf = (byte *)malloc(scriptSize);
WRITE_BE_UINT16(scriptBuf, 1); // One command
WRITE_BE_UINT16(scriptBuf + 2, argv[3]); // One opcode
- WRITE_BE_UINT16(scriptBuf + 4, argc - 4); // argc - 4 args
+ WRITE_BE_UINT16(scriptBuf + 4, argc - 4); // argc - 4 args
for (int i = 0; i < argc - 4; i++)
WRITE_BE_UINT16(scriptBuf + 6 + (i * 2), argv[i + 4]);
@@ -557,13 +561,11 @@ void RivenScript::storeMovieOpcode(uint16 op, uint16 argc, uint16 *argv) {
// Store the script
RivenScriptManager::StoredMovieOpcode storedOp;
storedOp.script = script;
- storedOp.time = delayTime + _vm->getTotalPlayTime();
+ storedOp.time = delayTime;
storedOp.id = argv[0];
- // TODO: Actually store the movie and call it in our movie loop
- // For now, just delete the script and move on
- //_vm->_scriptMan->setStoredMovieOpcode(storedOp);
- delete script;
+ // Store the opcode for later
+ _vm->_scriptMan->setStoredMovieOpcode(storedOp);
} else {
// Run immediately if we have no delay
script->runScript();
@@ -716,18 +718,10 @@ void RivenScriptManager::setStoredMovieOpcode(const StoredMovieOpcode &op) {
_storedMovieOpcode.time = op.time;
}
-void RivenScriptManager::runStoredMovieOpcode(uint16 id) {
+void RivenScriptManager::runStoredMovieOpcode() {
if (_storedMovieOpcode.script) {
- if (_storedMovieOpcode.id == id) {
- // If we've passed the time, run our script
- if (_vm->getTotalPlayTime() >= _storedMovieOpcode.time) {
- _storedMovieOpcode.script->runScript();
- clearStoredMovieOpcode();
- }
- } else {
- // We're on a completely different video, kill off any remaining opcode
- clearStoredMovieOpcode();
- }
+ _storedMovieOpcode.script->runScript();
+ clearStoredMovieOpcode();
}
}
diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h
index 75d4592e55..2932ba5939 100644
--- a/engines/mohawk/riven_scripts.h
+++ b/engines/mohawk/riven_scripts.h
@@ -141,8 +141,10 @@ public:
uint16 id;
};
+ uint16 getStoredMovieOpcodeID() { return _storedMovieOpcode.id; }
+ uint32 getStoredMovieOpcodeTime() { return _storedMovieOpcode.time; }
void setStoredMovieOpcode(const StoredMovieOpcode &op);
- void runStoredMovieOpcode(uint16 id);
+ void runStoredMovieOpcode();
void clearStoredMovieOpcode();
private:
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index 0a74d058c9..cd8fc8ef80 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -133,6 +133,7 @@ void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
break;
case Common::KEYCODE_ESCAPE:
continuePlaying = false;
+ _vm->doVideoTimer(videoHandle, true);
break;
default:
break;
@@ -208,14 +209,20 @@ bool VideoManager::updateMovies() {
if (_videoStreams[i].loop) {
_videoStreams[i]->seekToTime(_videoStreams[i].start);
} else {
+ // Check the video time one last time before deleting it
+ _vm->doVideoTimer(i, true);
delete _videoStreams[i].video;
_videoStreams[i].clear();
continue;
}
}
+ // Nothing more to do if we're paused
+ if (_videoStreams[i]->isPaused())
+ continue;
+
// Check if we need to draw a frame
- if (!_videoStreams[i]->isPaused() && _videoStreams[i]->needsUpdate()) {
+ if (_videoStreams[i]->needsUpdate()) {
const Graphics::Surface *frame = _videoStreams[i]->decodeNextFrame();
Graphics::Surface *convertedFrame = 0;
@@ -266,6 +273,9 @@ bool VideoManager::updateMovies() {
}
}
}
+
+ // Check the video time
+ _vm->doVideoTimer(i, false);
}
// Return true if we need to update the screen
@@ -426,22 +436,22 @@ VideoHandle VideoManager::createVideoHandle(const Common::String &filename, uint
entry.filename = filename;
entry.loop = loop;
entry.enabled = true;
-
+
Common::File *file = new Common::File();
if (!file->open(filename)) {
delete file;
return NULL_VID_HANDLE;
}
-
+
entry->loadStream(file);
-
+
// Search for any deleted videos so we can take a formerly used slot
for (uint32 i = 0; i < _videoStreams.size(); i++)
if (!_videoStreams[i].video) {
_videoStreams[i] = entry;
return i;
}
-
+
// Otherwise, just add it to the list
_videoStreams.push_back(entry);
return _videoStreams.size() - 1;
diff --git a/engines/obsolete.cpp b/engines/obsolete.cpp
new file mode 100644
index 0000000000..6733a384be
--- /dev/null
+++ b/engines/obsolete.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 "engines/obsolete.h"
+
+#include "common/config-manager.h"
+
+
+namespace Engines {
+
+void upgradeTargetIfNecessary(const ObsoleteGameID *obsoleteList) {
+ if (obsoleteList == 0)
+ return;
+
+ Common::String gameid = ConfMan.get("gameid");
+
+ for (const ObsoleteGameID *o = obsoleteList; o->from; ++o) {
+ if (gameid.equalsIgnoreCase(o->from)) {
+ gameid = o->to;
+ ConfMan.set("gameid", gameid);
+
+ if (o->platform != Common::kPlatformUnknown)
+ ConfMan.set("platform", Common::getPlatformCode(o->platform));
+
+ warning("Target upgraded from %s to %s", o->from, o->to);
+
+ // WORKAROUND: Fix for bug #1719463: "DETECTOR: Launching
+ // undefined target adds launcher entry"
+ if (ConfMan.hasKey("id_came_from_command_line")) {
+ warning("Target came from command line. Skipping save");
+ } else {
+ ConfMan.flushToDisk();
+ }
+ break;
+ }
+ }
+}
+
+GameDescriptor findGameID(
+ const char *gameid,
+ const PlainGameDescriptor *gameids,
+ const ObsoleteGameID *obsoleteList
+ ) {
+ // First search the list of supported gameids for a match.
+ const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, gameids);
+ if (g)
+ return GameDescriptor(*g);
+
+ // If we didn't find the gameid in the main list, check if it
+ // is an obsolete game id.
+ if (obsoleteList != 0) {
+ const ObsoleteGameID *o = obsoleteList;
+ while (o->from) {
+ if (0 == scumm_stricmp(gameid, o->from)) {
+ g = findPlainGameDescriptor(o->to, gameids);
+ if (g && g->description)
+ return GameDescriptor(gameid, "Obsolete game ID (" + Common::String(g->description) + ")");
+ else
+ return GameDescriptor(gameid, "Obsolete game ID");
+ }
+ o++;
+ }
+ }
+
+ // No match found
+ return GameDescriptor();
+}
+
+} // End of namespace Engines
diff --git a/engines/obsolete.h b/engines/obsolete.h
new file mode 100644
index 0000000000..97bc7524a6
--- /dev/null
+++ b/engines/obsolete.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 ENGINES_OBSOLETE_H
+#define ENGINES_OBSOLETE_H
+
+#include "engines/game.h"
+
+namespace Engines {
+
+/**
+ * Structure for autoupgrading targets using an obsolete gameid
+ * to the correct new gameid.
+ */
+struct ObsoleteGameID {
+
+ /** Name of the obsolete gameid. */
+ const char *from;
+
+ /** Name of the corresponding new gameid. */
+ const char *to;
+
+ /**
+ * If platform is set to a value different from Common::kPlatformUnknown,
+ * then upgradeTargetIfNecessary() will use this value to set the platform
+ * attribute of any target it updates using this ObsoleteGameID record.
+ * This is useful when the old gameid encoded the target platform (e.g.
+ * "zakTowns" for FM-TOWNS) while the new gameid does not (e.g. "zak").
+ */
+ Common::Platform platform;
+};
+
+/**
+ * Check if the currently active game target has an obsolete gameid;
+ * if so, replace it by the correct new gameid.
+ * This function is typically invoked by a MetaEngine::createInstance
+ * implementation.
+ */
+void upgradeTargetIfNecessary(const ObsoleteGameID *obsoleteList);
+
+
+/**
+ * Scan through the given list of plain game descriptors specified and search
+ * for 'gameid' in there. If a match is found, returns a GameDescriptor
+ * with gameid and description set.
+ *
+ * Optionally can take a list of obsolete game ids into account in order
+ * to support obsolete gameids.
+ */
+GameDescriptor findGameID(
+ const char *gameid,
+ const PlainGameDescriptor *gameids,
+ const ObsoleteGameID *obsoleteList = 0
+ );
+
+
+} // End of namespace Engines
+
+#endif
diff --git a/engines/parallaction/detection.cpp b/engines/parallaction/detection.cpp
index c3719bcd51..d0610f7a29 100644
--- a/engines/parallaction/detection.cpp
+++ b/engines/parallaction/detection.cpp
@@ -220,34 +220,11 @@ static const PARALLACTIONGameDescription gameDescriptions[] = {
}
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Parallaction::gameDescriptions,
- // Size of that superset structure
- sizeof(Parallaction::PARALLACTIONGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- parallactionGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class ParallactionMetaEngine : public AdvancedMetaEngine {
public:
- ParallactionMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ ParallactionMetaEngine() : AdvancedMetaEngine(Parallaction::gameDescriptions, sizeof(Parallaction::PARALLACTIONGameDescription), parallactionGames) {
+ _guioptions = Common::GUIO_NOLAUNCHLOAD;
+ }
virtual const char *getName() const {
return "Parallaction";
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index 880d41a8a3..a908152bf8 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -52,7 +52,7 @@ struct BalloonPositions {
class DialogueManager {
-
+
Parallaction *_vm;
Dialogue *_dialogue;
@@ -81,10 +81,10 @@ protected:
bool _isKeyDown;
uint16 _downKey;
-protected:
+protected:
Gfx *_gfx;
BalloonManager *_balloonMan;
-
+
public:
DialogueManager(Parallaction *vm, ZonePtr z);
virtual ~DialogueManager();
@@ -108,11 +108,11 @@ protected:
NEXT_ANSWER,
DIALOGUE_OVER
} _state;
-
+
static const int NO_ANSWER_SELECTED = -1;
void transitionToState(DialogueState newState);
-
+
bool displayQuestion();
void displayAnswers();
bool testAnswerFlags(Answer *a);
@@ -132,7 +132,7 @@ protected:
DialogueManager::DialogueManager(Parallaction *vm, ZonePtr z) : _vm(vm), _z(z) {
_gfx = _vm->_gfx;
_balloonMan = _vm->_balloonMan;
-
+
_dialogue = _z->u._speakDialogue;
isNpc = !_z->u._filename.empty() && _z->u._filename.compareToIgnoreCase("yourself");
_questioner = isNpc ? _vm->_disk->loadTalk(_z->u._filename.c_str()) : _vm->_char._talk;
@@ -166,11 +166,11 @@ void DialogueManager::transitionToState(DialogueState newState) {
"nextanswer",
"over"
};
-
+
if (_state != newState) {
debugC(3, kDebugDialogue, "DialogueManager moved to state '%s'", dialogueStates[newState]);
- if (DebugMan.isDebugChannelEnabled(kDebugDialogue) && gDebugLevel == 9) {
+ if (DebugMan.isDebugChannelEnabled(kDebugDialogue) && gDebugLevel == 9) {
switch (newState) {
case RUN_QUESTION:
debug(" Q : %s", _q->_text.c_str());
@@ -188,7 +188,7 @@ void DialogueManager::transitionToState(DialogueState newState) {
_state = newState;
}
-
+
bool DialogueManager::testAnswerFlags(Answer *a) {
uint32 flags = _vm->getLocationFlags();
if (a->_yesFlags & kFlagsGlobal)
@@ -240,7 +240,7 @@ int16 DialogueManager::selectAnswerN() {
VisibleAnswer *oldAnswer = &_visAnswers[_oldSelection];
VisibleAnswer *answer = &_visAnswers[_selection];
-
+
if (_selection != _oldSelection) {
if (_oldSelection != NO_ANSWER_SELECTED) {
_balloonMan->setBalloonText(oldAnswer->_balloon, oldAnswer->_a->_text, BalloonManager::kUnselectedColor);
@@ -286,7 +286,7 @@ void DialogueManager::nextAnswer() {
return;
}
- // try and check if there are any suitable answers,
+ // try and check if there are any suitable answers,
// given the current game state.
addVisibleAnswers(_q);
if (!_numVisAnswers) {
@@ -294,9 +294,9 @@ void DialogueManager::nextAnswer() {
transitionToState(DIALOGUE_OVER);
return;
}
-
+
if (_visAnswers[0]._a->textIsNull()) {
- // if the first answer is null (it's implied that it's the
+ // if the first answer is null (it's implied that it's the
// only one because we already called addVisibleAnswers),
// then jump to the next question
_answerId = _visAnswers[0]._index;
@@ -547,7 +547,7 @@ void Parallaction::runDialogueFrame() {
if (_input->_inputMode != Input::kInputModeDialogue) {
return;
}
-
+
_dialogueMan->run();
if (_dialogueMan->isOver()) {
diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp
index 0ec1675c48..658ef5af82 100644
--- a/engines/parallaction/exec_br.cpp
+++ b/engines/parallaction/exec_br.cpp
@@ -530,11 +530,11 @@ DECLARE_INSTRUCTION_OPCODE(endif) {
DECLARE_INSTRUCTION_OPCODE(stop) {
ZonePtr z = ctxt._inst->_z;
-
- // Prevent execution if zone is missing. The known case is "PART2/insegui.scr", which has
+
+ // Prevent execution if zone is missing. The known case is "PART2/insegui.scr", which has
// "STOP insegui", which doesn't exist (see ticket #3021744 for the gory details)
if (!z) return;
-
+
if (ACTIONTYPE(z) == kZoneHear) {
warning("Parallaction_br::instOp_stop not yet implemented for HEAR zones");
// TODO: stop music or sound effects generated by a zone.
diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp
index 24544f46dd..48d84ed101 100644
--- a/engines/parallaction/gfxbase.cpp
+++ b/engines/parallaction/gfxbase.cpp
@@ -296,19 +296,19 @@ void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *sur
// clipped scaled destination rectangle
Common::Rect dstRect(scaledWidth, scaledHeight);
dstRect.moveTo(scaledLeft, scaledTop);
-
- Common::Rect clipper(surf->w, surf->h);
+
+ Common::Rect clipper(surf->w, surf->h);
dstRect.clip(clipper);
if (!dstRect.isValidRect()) return;
-
-
+
+
// clipped source rectangle
Common::Rect srcRect;
srcRect.left = (dstRect.left - scaledLeft) * 100 / scale;
srcRect.top = (dstRect.top - scaledTop) * 100 / scale;
srcRect.setWidth(dstRect.width() * 100 / scale);
srcRect.setHeight(dstRect.height() * 100 / scale);
- if (!srcRect.isValidRect()) return;
+ if (!srcRect.isValidRect()) return;
Common::Point dp;
dp.x = dstRect.left;
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index cf0cf13333..1da61b68ae 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -565,7 +565,7 @@ void Gfx::showFloatingLabel(GfxObj *label) {
label->x = -1000;
label->y = -1000;
label->setFlags(kGfxObjVisible);
-
+
_floatingLabel = label;
_labels.push_back(label);
}
@@ -673,7 +673,7 @@ void Gfx::showLabel(GfxObj *label, int16 x, int16 y) {
label->x = x;
label->y = y;
-
+
_labels.push_back(label);
}
@@ -695,7 +695,7 @@ void Gfx::unregisterLabel(GfxObj *label) {
_labels.remove_at(i);
break;
}
- }
+ }
}
diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp
index c520ad4f25..d1361a6e8c 100644
--- a/engines/parallaction/gui_br.cpp
+++ b/engines/parallaction/gui_br.cpp
@@ -223,10 +223,10 @@ public:
}
break;
- default:
+ default:
_vm->_nextPart = _firstLocation[selection].part;
_vm->scheduleLocationSwitch(_firstLocation[selection].location);
-
+
}
_vm->_system->showMouse(false);
diff --git a/engines/parallaction/gui_ns.cpp b/engines/parallaction/gui_ns.cpp
index ef1a8a6e7e..3794aeae29 100644
--- a/engines/parallaction/gui_ns.cpp
+++ b/engines/parallaction/gui_ns.cpp
@@ -122,7 +122,7 @@ public:
_dosLanguageSelectBlocks[1] = Common::Rect( 129, 85, 177, 155 ); // French
_dosLanguageSelectBlocks[2] = Common::Rect( 178, 60, 226, 130 ); // English
_dosLanguageSelectBlocks[3] = Common::Rect( 227, 35, 275, 105 ); // German
-
+
_amigaLanguageSelectBlocks[0] = Common::Rect( -1, -1, -1, -1 ); // Italian: not supported by Amiga multi-lingual version
_amigaLanguageSelectBlocks[1] = Common::Rect( 129, 85, 177, 155 ); // French
_amigaLanguageSelectBlocks[2] = Common::Rect( 178, 60, 226, 130 ); // English
@@ -149,7 +149,7 @@ public:
_language = -1;
_allowChoice = true;
}
-
+
~ChooseLanguageInputState_NS() {
destroyLabels();
}
@@ -222,15 +222,15 @@ public:
_nextState[0] = "newgame";
_nextState[1] = "loadgame";
-
+
_labels[0] = 0;
_labels[1] = 0;
}
-
+
~SelectGameInputState_NS() {
destroyLabels();
}
-
+
void destroyLabels() {
_vm->_gfx->unregisterLabel(_labels[0]);
_vm->_gfx->unregisterLabel(_labels[1]);
@@ -326,7 +326,7 @@ public:
_labels[2] = 0;
_labels[3] = 0;
}
-
+
~NewGameInputState_NS() {
destroyLabels();
}
@@ -475,7 +475,7 @@ public:
_block.create(BLOCK_WIDTH, BLOCK_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
_labels[0] = 0;
_labels[1] = 0;
-
+
_codeSelectBlocks[0] = Common::Rect( 111, 129, 127, 153 ); // na
_codeSelectBlocks[1] = Common::Rect( 128, 120, 144, 144 ); // wa
_codeSelectBlocks[2] = Common::Rect( 145, 111, 161, 135 ); // ra
@@ -698,7 +698,7 @@ public:
_vm->_gfx->unregisterLabel(_labels[0]);
_vm->_gfx->unregisterLabel(_labels[1]);
delete _labels[0];
- delete _labels[1];
+ delete _labels[1];
_labels[0] = 0;
_labels[1] = 0;
}
@@ -827,18 +827,18 @@ public:
_labels[2] = 0;
_labels[3] = 0;
}
-
+
void destroyLabels() {
_vm->_gfx->unregisterLabel(_labels[0]);
_vm->_gfx->unregisterLabel(_labels[1]);
_vm->_gfx->unregisterLabel(_labels[2]);
_vm->_gfx->unregisterLabel(_labels[3]);
-
+
delete _labels[0];
delete _labels[1];
delete _labels[2];
delete _labels[3];
-
+
_labels[0] = 0;
_labels[1] = 0;
_labels[2] = 0;
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index 3750602076..22406013a1 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -264,7 +264,7 @@ bool Answer::textIsNull() {
int Answer::speakerMood() {
return _mood & 0xF;
}
-
+
Question::Question(const Common::String &name) : _name(name), _mood(0) {
memset(_answers, 0, sizeof(_answers));
}
@@ -278,16 +278,16 @@ Question::~Question() {
bool Question::textIsNull() {
return (_text.equalsIgnoreCase("NULL"));
}
-
+
int Question::speakerMood() {
return _mood & 0xF;
}
int Question::balloonWinding() {
- return _mood & 0x10;
+ return _mood & 0x10;
}
-
+
Instruction::Instruction() {
_index = 0;
_flags = 0;
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 9bbc7d0c57..a37c4439a1 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -627,7 +627,7 @@ bool Parallaction::checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
return false;
}
}
-
+
// WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
// instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
// but we need to check it separately here. The same workaround is applied in freeZones.
@@ -659,14 +659,14 @@ bool Parallaction::checkZoneType(ZonePtr z, uint32 type) {
if (_gameType == GType_BRA) {
if (type == 0) {
- if (ITEMTYPE(z) == 0) {
+ if (ITEMTYPE(z) == 0) {
if (ACTIONTYPE(z) != kZonePath) {
return true;
}
- }
+ }
if (ACTIONTYPE(z) == kZoneDoor) {
return true;
- }
+ }
}
}
@@ -751,7 +751,7 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
AnimationPtr a = *ait;
_a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
-
+
if (!_a) {
if (_gameType == GType_BRA && ACTIONTYPE(a) != kZoneTrap) {
continue;
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index 64cf1b437d..0b92db1f0a 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -351,7 +351,7 @@ void Parallaction_ns::changeLocation() {
// prevent music changes during the introduction
_soundManI->playLocationMusic(location);
}
-
+
_input->stopHovering();
// this is still needed to remove the floatingLabel
_gfx->freeLabels();
@@ -471,7 +471,7 @@ void Parallaction_ns::changeCharacter(const char *name) {
// prevent music changes during the introduction
_soundManI->playCharacterMusic(_char.getBaseName());
}
-
+
// The original engine used to reload 'common' only on loadgames. We are reloading here since 'common'
// contains character specific stuff. This causes crashes like bug #1816899, because parseLocation tries
// to reload scripts but the data archive selected is occasionally wrong. This has been solved by having
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index e4be53022e..df53ecca3f 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -524,14 +524,14 @@ DECLARE_COMMAND_PARSER(location) {
ctxt.cmd->_startPos.x = -1000;
ctxt.cmd->_startPos2.x = -1000;
if (_tokens[ctxt.nextToken][0] != '\0') {
- if (isdigit(_tokens[ctxt.nextToken][0]) || _tokens[ctxt.nextToken][0] == '-') {
+ if (isdigit(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
ctxt.cmd->_startPos.x = atoi(_tokens[ctxt.nextToken]);
ctxt.nextToken++;
ctxt.cmd->_startPos.y = atoi(_tokens[ctxt.nextToken]);
ctxt.nextToken++;
}
- if (isdigit(_tokens[ctxt.nextToken][0]) || _tokens[ctxt.nextToken][0] == '-') {
+ if (isdigit(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
ctxt.cmd->_startPos2.x = atoi(_tokens[ctxt.nextToken]);
ctxt.nextToken++;
ctxt.cmd->_startPos2.y = atoi(_tokens[ctxt.nextToken]);
@@ -677,7 +677,7 @@ DECLARE_COMMAND_PARSER(text) {
createCommand(_parser->_lookup);
- if (isdigit(_tokens[1][1])) {
+ if (isdigit(static_cast<unsigned char>(_tokens[1][1]))) {
ctxt.cmd->_zeta0 = atoi(_tokens[1]);
ctxt.nextToken++;
} else {
@@ -714,7 +714,7 @@ DECLARE_COMMAND_PARSER(unary) {
DECLARE_ZONE_PARSER(limits) {
debugC(7, kDebugParser, "ZONE_PARSER(limits) ");
- if (isalpha(_tokens[1][1])) {
+ if (isalpha(static_cast<unsigned char>(_tokens[1][1]))) {
ctxt.z->_flags |= kFlagsAnimLinked;
ctxt.z->_linkedName = _tokens[1];
} else {
@@ -824,12 +824,12 @@ void LocationParser_br::parseHearData(ZonePtr z) {
}
void LocationParser_br::parseNoneData(ZonePtr z) {
- /* the only case we have to handle here is that of "scende2", which is the only Animation with
+ /* the only case we have to handle here is that of "scende2", which is the only Animation with
a command list following the type marker.
*/
if (!scumm_stricmp(_tokens[0], "commands")) {
parseCommands(z->_commands);
- }
+ }
}
@@ -1003,7 +1003,7 @@ DECLARE_INSTRUCTION_PARSER(text) {
int _si = 1;
- if (isdigit(_tokens[1][1])) {
+ if (isdigit(static_cast<unsigned char>(_tokens[1][1]))) {
ctxt.inst->_y = atoi(_tokens[1]);
_si = 2;
} else {
@@ -1066,7 +1066,7 @@ DECLARE_INSTRUCTION_PARSER(endif) {
void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) {
- if (isdigit(str[0]) || str[0] == '-') {
+ if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
v.setImmediate(atoi(str));
return;
}
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 69763affc8..100b608172 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -534,7 +534,7 @@ DECLARE_INSTRUCTION_PARSER(endscript) {
void ProgramParser_ns::parseRValue(ScriptVar &v, const char *str) {
- if (isdigit(str[0]) || str[0] == '-') {
+ if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
v.setImmediate(atoi(str));
return;
}
@@ -1412,9 +1412,9 @@ void LocationParser_ns::parseSpeakData(ZonePtr z) {
}
void LocationParser_ns::parseNoneData(ZonePtr z) {
- // "None" zones should have no content, but some
- // inconsistently define their command list after
- // the TYPE marker. This routine catches these
+ // "None" zones should have no content, but some
+ // inconsistently define their command list after
+ // the TYPE marker. This routine catches these
// command lists that would be lost otherwise.
if (!scumm_stricmp(_tokens[0], "commands")) {
parseCommands(z->_commands);
@@ -1423,7 +1423,7 @@ void LocationParser_ns::parseNoneData(ZonePtr z) {
_script->readLineToken(true);
_parser->parseStatement();
} while (!ctxt.endcommands);
-
+
// no need to parse one more line here, as
// it is done by the caller
}
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 673c613485..5a1daa256b 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -23,6 +23,7 @@
#include "common/savefile.h"
#include "common/config-manager.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "gui/dialog.h"
#include "gui/saveload.h"
@@ -129,8 +130,7 @@ void SaveLoad_ns::doLoadGame(uint16 slot) {
void SaveLoad_ns::doSaveGame(uint16 slot, const char* name) {
Common::OutSaveFile *f = getOutSaveFile(slot);
if (f == 0) {
- char buf[32];
- sprintf(buf, "Can't save game in slot %i\n\n", slot);
+ Common::String buf = Common::String::format(_("Can't save game in slot %i\n\n"), slot);
GUI::MessageDialog dialog(buf);
dialog.runModal();
return;
@@ -208,7 +208,7 @@ bool SaveLoad::loadGame() {
doLoadGame(_di);
- GUI::TimedMessageDialog dialog("Loading game...", 1500);
+ GUI::TimedMessageDialog dialog(_("Loading game..."), 1500);
dialog.runModal();
return true;
@@ -223,7 +223,7 @@ bool SaveLoad::saveGame() {
doSaveGame(slot, saveName.c_str());
- GUI::TimedMessageDialog dialog("Saving game...", 1500);
+ GUI::TimedMessageDialog dialog(_("Saving game..."), 1500);
dialog.runModal();
return true;
@@ -276,9 +276,9 @@ void SaveLoad_ns::getGamePartProgress(bool *complete, int size) {
static bool askRenameOldSavefiles() {
GUI::MessageDialog dialog0(
- "ScummVM found that you have old savefiles for Nippon Safes that should be renamed.\n"
+ _("ScummVM found that you have old savefiles for Nippon Safes that should be renamed.\n"
"The old names are no longer supported, so you will not be able to load your games if you don't convert them.\n\n"
- "Press OK to convert them now, otherwise you will be asked next time.\n", "OK", "Cancel");
+ "Press OK to convert them now, otherwise you will be asked next time.\n"), _("OK"), _("Cancel"));
return (dialog0.runModal() != 0);
}
@@ -321,12 +321,11 @@ void SaveLoad_ns::renameOldSavefiles() {
return;
}
- char msg[200];
+ Common::String msg;
if (success == numOldSaves) {
- sprintf(msg, "ScummVM successfully converted all your savefiles.");
+ msg = _("ScummVM successfully converted all your savefiles.");
} else {
- sprintf(msg,
- "ScummVM printed some warnings in your console window and can't guarantee all your files have been converted.\n\n"
+ msg = _("ScummVM printed some warnings in your console window and can't guarantee all your files have been converted.\n\n"
"Please report to the team.");
}
diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h
index baca5a7213..d0b5e5c175 100644
--- a/engines/parallaction/sound.h
+++ b/engines/parallaction/sound.h
@@ -131,11 +131,11 @@ class DosSoundMan_ns : public SoundMan_ns {
MidiPlayer *_midiPlayer;
bool _playing;
-
+
bool isLocationSilent(const char *locationName);
bool locationHasOwnSoftMusic(const char *locationName);
-
+
public:
DosSoundMan_ns(Parallaction_ns *vm);
~DosSoundMan_ns();
diff --git a/engines/parallaction/sound_ns.cpp b/engines/parallaction/sound_ns.cpp
index 917d310738..b5d4c72ea4 100644
--- a/engines/parallaction/sound_ns.cpp
+++ b/engines/parallaction/sound_ns.cpp
@@ -140,7 +140,7 @@ void DosSoundMan_ns::playMusic() {
Common::SeekableReadStream *stream = _vm->_disk->loadMusic(_musicFile);
_midiPlayer->play(stream);
_midiPlayer->setVolume(255);
-
+
_playing = true;
}
@@ -159,7 +159,7 @@ void DosSoundMan_ns::pause(bool p) {
bool DosSoundMan_ns::locationHasOwnSoftMusic(const char *locationName) {
return !scumm_stricmp(locationName, "night") || !scumm_stricmp(locationName, "intsushi");
}
-
+
void DosSoundMan_ns::playCharacterMusic(const char *character) {
if (!character || locationHasOwnSoftMusic(_vm->_location._name)) {
return;
@@ -167,7 +167,7 @@ void DosSoundMan_ns::playCharacterMusic(const char *character) {
char *name = const_cast<char*>(character);
const char *newMusicFile = 0;
-
+
if (!scumm_stricmp(name, _dinoName)) {
newMusicFile = "dino";
} else
@@ -200,7 +200,7 @@ void DosSoundMan_ns::playLocationMusic(const char *location) {
debugC(2, kDebugExec, "changeLocation: music stopped");
} else {
playCharacterMusic(_vm->_char.getBaseName());
- }
+ }
}
diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp
index 21ee5ee5d9..5d5695ace4 100644
--- a/engines/parallaction/walk.cpp
+++ b/engines/parallaction/walk.cpp
@@ -590,14 +590,14 @@ void PathWalker_BR::doWalk(State &s) {
int xStep = (scale * 16) / 100 + 1;
int yStep = (scale * 10) / 100 + 1;
- /* WORKAROUND: in the balloon scene, the position of the balloon (which is implemented as a
+ /* WORKAROUND: in the balloon scene, the position of the balloon (which is implemented as a
Character) is controlled by the user (for movement, via this walking code) and by the scripts
(to simulate the balloon floating in the air, in a neverending loop that alters the position
coordinates).
When the two step sizes are equal in magnitude and opposite in direction, then the walk code
enters an infinite loop without giving control back to the user (this happens quite frequently
- when navigating the balloon near the borders of the screen, where the calculated step is
- forcibly small because of clipping). Since the "floating" script (part1/scripts/mongolo.scr)
+ when navigating the balloon near the borders of the screen, where the calculated step is
+ forcibly small because of clipping). Since the "floating" script (part1/scripts/mongolo.scr)
uses increments of 3 for both x and y, we tweak the calculated steps accordingly here. */
if (xStep == 3) xStep--;
if (yStep == 3) yStep--;
diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp
index b83bf60435..1f8d9b29f9 100644
--- a/engines/queen/talk.cpp
+++ b/engines/queen/talk.cpp
@@ -658,7 +658,7 @@ void Talk::stringAnimation(const SpeechParameters *parameters, int startFrame, i
} else if (parameters->animation[0] == 'E') {
// Talking head animation
return;
- } else if (!isdigit(parameters->animation[0])) {
+ } else if (!isdigit(static_cast<unsigned char>(parameters->animation[0]))) {
debug(6, "Error in speak string animation: '%s'", parameters->animation);
return;
} else
diff --git a/engines/saga/actor.cpp b/engines/saga/actor.cpp
index 86606855e3..06ce335518 100644
--- a/engines/saga/actor.cpp
+++ b/engines/saga/actor.cpp
@@ -340,7 +340,7 @@ void Actor::loadActorSpriteList(ActorData *actor) {
uint lastFrame = 0;
uint curFrameIndex;
int resourceId = actor->_spriteListResourceId;
-
+
if (actor->_frames != NULL) {
for (ActorFrameSequences::const_iterator i = actor->_frames->begin(); i != actor->_frames->end(); ++i) {
for (int orient = 0; orient < ACTOR_DIRECTIONS_COUNT; orient++) {
@@ -385,6 +385,7 @@ void Actor::loadActorList(int protagonistIdx, int actorCount, int actorsResource
ByteArrayReadStreamEndian actorS(actorListData);
+ _actors.clear();
_actors.resize(actorCount);
i = 0;
for (ActorDataArray::iterator actor = _actors.begin(); actor != _actors.end(); ++actor, i++) {
diff --git a/engines/saga/actor.h b/engines/saga/actor.h
index 451497986d..a4f475660d 100644
--- a/engines/saga/actor.h
+++ b/engines/saga/actor.h
@@ -321,7 +321,7 @@ public:
_screenDepth = in->readSint32LE();
_screenScale = in->readSint32LE();
}
-
+
CommonObjectData() {
_index = 0;
_id = 0;
@@ -463,7 +463,7 @@ public:
void cmdActorWalkTo(int argc, const char **argv);
bool validActorId(uint16 id) {
- return (id == ID_PROTAG) || ((id >= objectIndexToId(kGameObjectActor, 0)) && (id < objectIndexToId(kGameObjectActor, _actors.size())));
+ return (id == ID_PROTAG) || ((id >= objectIndexToId(kGameObjectActor, 0)) && (id < objectIndexToId(kGameObjectActor, _actors.size())));
}
int actorIdToIndex(uint16 id) { return (id == ID_PROTAG) ? 0 : objectIdToIndex(id); }
uint16 actorIndexToId(int index) { return (index == 0) ? ID_PROTAG : objectIndexToId(kGameObjectActor, index); }
diff --git a/engines/saga/actor_walk.cpp b/engines/saga/actor_walk.cpp
index 5607fcdd66..ea33a0950d 100644
--- a/engines/saga/actor_walk.cpp
+++ b/engines/saga/actor_walk.cpp
@@ -1165,7 +1165,15 @@ void Actor::moveDragon(ActorData *actor) {
dir0 = actor->_actionDirection;
dir1 = actor->_tileDirections[actor->_walkStepIndex++];
dir2 = actor->_tileDirections[actor->_walkStepIndex];
- dir3 = actor->_tileDirections[actor->_walkStepIndex + 1];
+ // Fix for Bug #3324850 ("ITE (SAGA): crash in dog sewers")
+ // If there were more than two steps left, get the third (next) step.
+ // Otherwise, store the second step again so the anim looks right.
+ // (If you stop the move instead, Rif isn't automatically knocked into
+ // the Sewer.)
+ if (actor->_walkStepIndex + 1 < actor->_walkStepsCount)
+ dir3 = actor->_tileDirections[actor->_walkStepIndex + 1];
+ else
+ dir3 = dir2;
if (dir0 != dir1){
actor->_actionDirection = dir0 = dir1;
diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp
index 7ec4a59398..8b2d1e9dad 100644
--- a/engines/saga/animation.cpp
+++ b/engines/saga/animation.cpp
@@ -169,7 +169,7 @@ int Anim::playCutaway(int cut, bool fade) {
ByteArray resourceData;
_vm->_resource->loadResource(context, _cutawayList[cut].animResourceId, resourceData);
load(MAX_ANIMATIONS + cutawaySlot, resourceData);
-
+
setCycles(MAX_ANIMATIONS + cutawaySlot, _cutawayList[cut].cycles);
setFrameTime(MAX_ANIMATIONS + cutawaySlot, 1000 / _cutawayList[cut].frameRate);
@@ -414,7 +414,7 @@ void Anim::load(uint16 animId, const ByteArray &resourceData) {
}
anim->resourceData.resize(resourceData.size() - dataOffset);
-
+
memcpy(anim->resourceData.getBuffer(), resourceData.getBuffer() + dataOffset, anim->resourceData.size());
// Cache frame offsets
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 23bdc73666..7a98fe4164 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -28,6 +28,7 @@
#include "common/config-manager.h"
#include "engines/advancedDetector.h"
+#include "engines/obsolete.h"
#include "common/system.h"
#include "graphics/thumbnail.h"
@@ -91,7 +92,7 @@ static const PlainGameDescriptor sagaGames[] = {
{0, 0}
};
-static const ADObsoleteGameID obsoleteGameIDsTable[] = {
+static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = {
{"ite", "saga", Common::kPlatformUnknown},
{"ihnm", "saga", Common::kPlatformUnknown},
{"dino", "saga", Common::kPlatformUnknown},
@@ -101,34 +102,15 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
#include "saga/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Saga::gameDescriptions,
- // Size of that superset structure
- sizeof(Saga::SAGAGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- sagaGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- "saga",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class SagaMetaEngine : public AdvancedMetaEngine {
public:
- SagaMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ SagaMetaEngine() : AdvancedMetaEngine(Saga::gameDescriptions, sizeof(Saga::SAGAGameDescription), sagaGames) {
+ _singleid = "saga";
+ }
+
+ virtual GameDescriptor findGame(const char *gameid) const {
+ return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable);
+ }
virtual const char *getName() const {
return "SAGA ["
@@ -157,7 +139,13 @@ public:
}
virtual bool hasFeature(MetaEngineFeature f) const;
+
+ virtual Common::Error createInstance(OSystem *syst, Engine **engine) const {
+ Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable);
+ return AdvancedMetaEngine::createInstance(syst, engine);
+ }
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+
virtual SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
virtual void removeSaveState(const char *target, int slot) const;
diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h
index f63efd206b..ab73fcba6e 100644
--- a/engines/saga/detection_tables.h
+++ b/engines/saga/detection_tables.h
@@ -821,7 +821,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GID_DINO,
@@ -851,7 +851,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO_NONE
},
GID_FTA2,
diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp
index 35f41e30ab..ec3ef2f6f9 100644
--- a/engines/saga/events.cpp
+++ b/engines/saga/events.cpp
@@ -557,7 +557,7 @@ int Events::handleInterval(Event *event) {
}
EventColumns *Events::chain(EventColumns *eventColumns, const Event &event) {
-
+
if (eventColumns == NULL) {
EventColumns tmp;
diff --git a/engines/saga/introproc_saga2.cpp b/engines/saga/introproc_saga2.cpp
index 80d53a2794..bdf8936a55 100644
--- a/engines/saga/introproc_saga2.cpp
+++ b/engines/saga/introproc_saga2.cpp
@@ -113,7 +113,7 @@ void Scene::playMovie(const char *filename) {
_vm->_system->updateScreen();
}
}
-
+
Common::Event event;
while (_vm->_system->getEventManager()->pollEvent(event)) {
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp
index adea59ca9a..e886f0df82 100644
--- a/engines/saga/isomap.cpp
+++ b/engines/saga/isomap.cpp
@@ -836,7 +836,7 @@ void IsoMap::drawTile(uint16 tileIndex, const Point &point, const Location *loca
count = colDiff;
col += colDiff;
}
-
+
colDiff = _tileClip.right - col;
if (colDiff > 0) {
int countDiff = fgRunCount - count;
diff --git a/engines/saga/palanim.cpp b/engines/saga/palanim.cpp
index 1fefad93ab..021a4c9bac 100644
--- a/engines/saga/palanim.cpp
+++ b/engines/saga/palanim.cpp
@@ -53,7 +53,7 @@ void PalAnim::loadPalAnim(const ByteArray &resourceData) {
debug(3, "PalAnim::loadPalAnim(): Loading %d PALANIM entries.", _entries.size());
for (Common::Array<PalanimEntry>::iterator i = _entries.begin(); i != _entries.end(); ++i) {
-
+
i->cycle = 0;
i->colors.resize(readS.readUint16());
@@ -139,7 +139,7 @@ void PalAnim::cycleStep(int vectortime) {
void PalAnim::clear() {
debug(3, "PalAnim::clear()");
-
+
_entries.clear();
}
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
index 15bd2aff72..d168605e99 100644
--- a/engines/saga/saga.cpp
+++ b/engines/saga/saga.cpp
@@ -451,7 +451,7 @@ void SagaEngine::loadStrings(StringsTable &stringsTable, const ByteArray &string
error("SagaEngine::loadStrings() Wrong offset");
}
stringsTable.strings[ui] = &stringsTable.buffer[offset];
-
+
debug(9, "string[%i]=%s", ui, stringsTable.strings[ui]);
}
}
diff --git a/engines/saga/scene.h b/engines/saga/scene.h
index adac3b622a..6e2cb12380 100644
--- a/engines/saga/scene.h
+++ b/engines/saga/scene.h
@@ -126,7 +126,7 @@ struct SceneDescription {
uint16 sceneScriptEntrypointNumber;
uint16 startScriptEntrypointNumber;
int16 musicResourceId;
-
+
void reset() {
flags = resourceListResourceId = endSlope = beginSlope = scriptModuleNumber = sceneScriptEntrypointNumber = startScriptEntrypointNumber = musicResourceId = 0;
}
diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp
index 81893c7480..2895c6800c 100644
--- a/engines/saga/sprite.cpp
+++ b/engines/saga/sprite.cpp
@@ -207,7 +207,7 @@ void Sprite::drawClip(const Point &spritePointer, int width, int height, const b
const byte *srcPointer;
int backBufferPitch = _vm->_gfx->getBackBufferPitch();
-
+
//find Rects intersection
yDiff = clipRect.top - spritePointer.y;
if (yDiff > 0) {
@@ -247,10 +247,10 @@ void Sprite::drawClip(const Point &spritePointer, int width, int height, const b
}
bufRowPointer = _vm->_gfx->getBackBufferPixels() + backBufferPitch * yDstOffset + xDstOffset;
srcRowPointer = spriteBuffer + width * ySrcOffset + xSrcOffset;
-
+
// validate src, dst buffers
assert(_vm->_gfx->getBackBufferPixels() <= bufRowPointer);
- assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayInfo().width * _vm->getDisplayInfo().height)) >=
+ assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayInfo().width * _vm->getDisplayInfo().height)) >=
(byte *)(bufRowPointer + backBufferPitch * (cHeight - 1) + cWidth));
assert((const byte *)spriteBuffer <= srcRowPointer);
assert(((const byte *)spriteBuffer + (width * height)) >= (const byte *)(srcRowPointer + width * (cHeight - 1) + cWidth));
@@ -469,7 +469,7 @@ void Sprite::scaleBuffer(const byte *src, int width, int height, int scale, size
_decodeBuf.resize(outLength);
byte *dst = &_decodeBuf.front();
-
+
memset(dst, 0, _decodeBuf.size());
for (int i = 0; i < height; i++) {
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index af945247ba..2f69d5caa1 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -131,6 +131,8 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
DCmd_Register("al", WRAP_METHOD(Console, cmdAnimateList)); // alias
DCmd_Register("window_list", WRAP_METHOD(Console, cmdWindowList));
DCmd_Register("wl", WRAP_METHOD(Console, cmdWindowList)); // alias
+ DCmd_Register("saved_bits", WRAP_METHOD(Console, cmdSavedBits));
+ DCmd_Register("show_saved_bits", WRAP_METHOD(Console, cmdShowSavedBits));
// Segments
DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
@@ -253,7 +255,7 @@ void Console::postEnter() {
videoDecoder = new RobotDecoder(g_system->getMixer(), _engine->getPlatform() == Common::kPlatformMacintosh);
} else if (_videoFile.hasSuffix(".duk")) {
duckMode = true;
- videoDecoder = new Video::AviDecoder(g_system->getMixer());
+ videoDecoder = new Video::AviDecoder(g_system->getMixer());
#endif
} else if (_videoFile.hasSuffix(".avi")) {
videoDecoder = new Video::AviDecoder(g_system->getMixer());
@@ -364,6 +366,8 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" undither - Enable/disable undithering\n");
DebugPrintf(" play_video - Plays a SEQ, AVI, VMD, RBT or DUK video\n");
DebugPrintf(" animate_object_list / al - Shows the current list of objects in kAnimate's draw list\n");
+ DebugPrintf(" saved_bits - List saved bits on the hunk\n");
+ DebugPrintf(" show_saved_bits - Display saved bits\n");
DebugPrintf("\n");
DebugPrintf("Segments:\n");
DebugPrintf(" segment_table / segtable - Lists all segments\n");
@@ -891,7 +895,7 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) {
return true;
}
-// Same as in sound/drivers/midi.cpp
+// Same as in sound/drivers/midi.cpp
uint8 getGmInstrument(const Mt32ToGmMap &Mt32Ins) {
if (Mt32Ins.gmInstr == MIDI_MAPPED_TO_RHYTHM)
return Mt32Ins.gmRhythmKey + 0x80;
@@ -909,7 +913,7 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
MidiPlayer *player = MidiPlayer_Midi_create(doSoundVersion);
MidiParser_SCI *parser = new MidiParser_SCI(doSoundVersion, 0);
parser->setMidiDriver(player);
-
+
Common::List<ResourceId> *resources = _engine->getResMan()->listResources(kResourceTypeSound);
Common::sort(resources->begin(), resources->end());
Common::List<ResourceId>::iterator itr = resources->begin();
@@ -980,7 +984,7 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
if (channel != 15) { // SCI special
byte instrument = *channelData++;
if (!firstOneShown)
- firstOneShown = true;
+ firstOneShown = true;
else
DebugPrintf(",");
@@ -1573,7 +1577,7 @@ bool Console::cmdPlayVideo(int argc, const char **argv) {
Common::String filename = argv[1];
filename.toLowercase();
- if (filename.hasSuffix(".seq") || filename.hasSuffix(".avi") || filename.hasSuffix(".vmd") ||
+ if (filename.hasSuffix(".seq") || filename.hasSuffix(".avi") || filename.hasSuffix(".vmd") ||
filename.hasSuffix(".rbt") || filename.hasSuffix(".duk")) {
_videoFile = filename;
_videoFrameDelay = (argc == 2) ? 10 : atoi(argv[2]);
@@ -1600,6 +1604,174 @@ bool Console::cmdWindowList(int argc, const char **argv) {
return true;
}
+
+bool Console::cmdSavedBits(int argc, const char **argv) {
+ SegManager *segman = _engine->_gamestate->_segMan;
+ SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
+ HunkTable* hunks = (HunkTable*)segman->getSegmentObj(id);
+ if (!hunks) {
+ DebugPrintf("No hunk segment found.\n");
+ return true;
+ }
+
+ Common::Array<reg_t> entries = hunks->listAllDeallocatable(id);
+
+ for (uint i = 0; i < entries.size(); ++i) {
+ uint16 offset = entries[i].offset;
+ const Hunk& h = hunks->_table[offset];
+ if (strcmp(h.type, "SaveBits()") == 0) {
+ byte* memoryPtr = (byte*)h.mem;
+
+ if (memoryPtr) {
+ DebugPrintf("%04x:%04x:", PRINT_REG(entries[i]));
+
+ Common::Rect rect;
+ byte mask;
+ assert(h.size >= sizeof(rect) + sizeof(mask));
+
+ memcpy((void *)&rect, memoryPtr, sizeof(rect));
+ memcpy((void *)&mask, memoryPtr + sizeof(rect), sizeof(mask));
+
+ DebugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
+ rect.bottom, rect.right);
+ if (mask & GFX_SCREEN_MASK_VISUAL)
+ DebugPrintf(" visual");
+ if (mask & GFX_SCREEN_MASK_PRIORITY)
+ DebugPrintf(" priority");
+ if (mask & GFX_SCREEN_MASK_CONTROL)
+ DebugPrintf(" control");
+ if (mask & GFX_SCREEN_MASK_DISPLAY)
+ DebugPrintf(" display");
+ DebugPrintf("\n");
+ }
+ }
+ }
+
+
+ return true;
+}
+
+bool Console::cmdShowSavedBits(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Display saved bits.\n");
+ DebugPrintf("Usage: %s <address>\n", argv[0]);
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ reg_t memoryHandle = NULL_REG;
+
+ if (parse_reg_t(_engine->_gamestate, argv[1], &memoryHandle, false)) {
+ DebugPrintf("Invalid address passed.\n");
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ if (memoryHandle.isNull()) {
+ DebugPrintf("Invalid address.\n");
+ return true;
+ }
+
+ SegManager *segman = _engine->_gamestate->_segMan;
+ SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
+ HunkTable* hunks = (HunkTable*)segman->getSegmentObj(id);
+ if (!hunks) {
+ DebugPrintf("No hunk segment found.\n");
+ return true;
+ }
+
+ if (memoryHandle.segment != id || !hunks->isValidOffset(memoryHandle.offset)) {
+ DebugPrintf("Invalid address.\n");
+ return true;
+ }
+
+ const Hunk& h = hunks->_table[memoryHandle.offset];
+
+ if (strcmp(h.type, "SaveBits()") != 0) {
+ DebugPrintf("Invalid address.\n");
+ return true;
+ }
+
+ byte *memoryPtr = segman->getHunkPointer(memoryHandle);
+
+ if (!memoryPtr) {
+ DebugPrintf("Invalid or freed bits.\n");
+ return true;
+ }
+
+ // Now we _finally_ know these are valid saved bits
+
+ Common::Rect rect;
+ byte mask;
+ assert(h.size >= sizeof(rect) + sizeof(mask));
+
+ memcpy((void *)&rect, memoryPtr, sizeof(rect));
+ memcpy((void *)&mask, memoryPtr + sizeof(rect), sizeof(mask));
+
+ Common::Point tl(rect.left, rect.top);
+ Common::Point tr(rect.right-1, rect.top);
+ Common::Point bl(rect.left, rect.bottom-1);
+ Common::Point br(rect.right-1, rect.bottom-1);
+
+ DebugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
+ rect.bottom, rect.right);
+ if (mask & GFX_SCREEN_MASK_VISUAL)
+ DebugPrintf(" visual");
+ if (mask & GFX_SCREEN_MASK_PRIORITY)
+ DebugPrintf(" priority");
+ if (mask & GFX_SCREEN_MASK_CONTROL)
+ DebugPrintf(" control");
+ if (mask & GFX_SCREEN_MASK_DISPLAY)
+ DebugPrintf(" display");
+ DebugPrintf("\n");
+
+ if (!_engine->_gfxPaint16 || !_engine->_gfxScreen)
+ return true;
+
+ // We backup all planes, and then flash the saved bits
+ // FIXME: This probably won't work well with hi-res games
+
+ byte bakMask = GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY | GFX_SCREEN_MASK_CONTROL;
+ int bakSize = _engine->_gfxScreen->bitsGetDataSize(rect, bakMask);
+ reg_t bakScreen = segman->allocateHunkEntry("show_saved_bits backup", bakSize);
+ byte* bakMemory = segman->getHunkPointer(bakScreen);
+ assert(bakMemory);
+ _engine->_gfxScreen->bitsSave(rect, bakMask, bakMemory);
+
+#ifndef USE_TEXT_CONSOLE_FOR_DEBUGGER
+ // If a graphical debugger overlay is used, hide it here, so that the
+ // results can be drawn.
+ g_system->hideOverlay();
+#endif
+
+ const int paintCount = 3;
+ for (int i = 0; i < paintCount; ++i) {
+ _engine->_gfxScreen->bitsRestore(memoryPtr);
+ _engine->_gfxScreen->drawLine(tl, tr, 0, 255, 255);
+ _engine->_gfxScreen->drawLine(tr, br, 0, 255, 255);
+ _engine->_gfxScreen->drawLine(br, bl, 0, 255, 255);
+ _engine->_gfxScreen->drawLine(bl, tl, 0, 255, 255);
+ _engine->_gfxScreen->copyRectToScreen(rect);
+ g_system->updateScreen();
+ g_sci->sleep(500);
+ _engine->_gfxScreen->bitsRestore(bakMemory);
+ _engine->_gfxScreen->copyRectToScreen(rect);
+ g_system->updateScreen();
+ if (i < paintCount - 1)
+ g_sci->sleep(500);
+ }
+
+ _engine->_gfxPaint16->bitsFree(bakScreen);
+
+#ifndef USE_TEXT_CONSOLE_FOR_DEBUGGER
+ // Show the graphical debugger overlay
+ g_system->showOverlay();
+#endif
+
+ return true;
+}
+
+
bool Console::cmdParseGrammar(int argc, const char **argv) {
DebugPrintf("Parse grammar, in strict GNF:\n");
@@ -1657,7 +1829,7 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
case SEG_TYPE_STRING:
DebugPrintf("T SCI32 strings (%d)", (*(StringTable *)mobj).entries_used);
break;
-#endif
+#endif
default:
DebugPrintf("I Invalid (type = %x)", mobj->getType());
@@ -2782,8 +2954,8 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
uint16 argc2 = opparams[1];
if (kFuncNum == kernelFuncNum) {
- DebugPrintf("Called from script %d, object %s, method %s(%d) with %d parameters\n",
- itr->getNumber(), objName,
+ DebugPrintf("Called from script %d, object %s, method %s(%d) with %d bytes for arguments\n",
+ itr->getNumber(), objName,
_engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), i, argc2);
}
}
@@ -2799,7 +2971,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
// Check for end of function/script
if (offset >= script->getBufSize())
break;
- if (opcode == op_ret)// && offset >= maxJmpOffset)
+ if (opcode == op_ret && offset >= maxJmpOffset)
break;
} // while (true)
} // for (uint16 i = 0; i < obj->getMethodCount(); i++)
diff --git a/engines/sci/console.h b/engines/sci/console.h
index 1e2ebe4ba2..d943923ba1 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -94,6 +94,8 @@ private:
bool cmdPlayVideo(int argc, const char **argv);
bool cmdAnimateList(int argc, const char **argv);
bool cmdWindowList(int argc, const char **argv);
+ bool cmdSavedBits(int argc, const char **argv);
+ bool cmdShowSavedBits(int argc, const char **argv);
// Segments
bool cmdPrintSegmentTable(int argc, const char **argv);
bool cmdSegmentInfo(int argc, const char **argv);
diff --git a/engines/sci/decompressor.cpp b/engines/sci/decompressor.cpp
index 03a06d240d..82af6eca43 100644
--- a/engines/sci/decompressor.cpp
+++ b/engines/sci/decompressor.cpp
@@ -181,16 +181,27 @@ int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPack
init(src, dest, nPacked, nUnpacked);
uint16 token; // The last received value
-
- uint16 tokenlist[4096]; // pointers to dest[]
- uint16 tokenlengthlist[4096]; // char length of each token
uint16 tokenlastlength = 0;
+ uint16 *tokenlist = (uint16 *)malloc(4096 * sizeof(uint16)); // pointers to dest[]
+ uint16* tokenlengthlist = (uint16 *)malloc(4096 * sizeof(uint16)); // char length of each token
+ if (!tokenlist || !tokenlengthlist) {
+ free(tokenlist);
+ free(tokenlengthlist);
+
+ error("[DecompressorLZW::unpackLZW] Cannot allocate token memory buffers");
+ }
+
while (!isFinished()) {
token = getBitsLSB(_numbits);
- if (token == 0x101)
+ if (token == 0x101) {
+ free(tokenlist);
+ free(tokenlengthlist);
+
return 0; // terminator
+ }
+
if (token == 0x100) { // reset command
_numbits = 9;
_endtoken = 0x1FF;
@@ -199,6 +210,10 @@ int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPack
if (token > 0xff) {
if (token >= _curtoken) {
warning("unpackLZW: Bad token %x", token);
+
+ free(tokenlist);
+ free(tokenlengthlist);
+
return SCI_ERROR_DECOMPRESSION_ERROR;
}
tokenlastlength = tokenlengthlist[token] + 1;
@@ -231,6 +246,9 @@ int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPack
}
}
+ free(tokenlist);
+ free(tokenlengthlist);
+
return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
}
@@ -238,12 +256,20 @@ int DecompressorLZW::unpackLZW1(Common::ReadStream *src, byte *dest, uint32 nPac
uint32 nUnpacked) {
init(src, dest, nPacked, nUnpacked);
- byte stak[0x1014];
+ byte *stak = (byte *)malloc(0x1014);
+ unsigned int tokensSize = 0x1004 * sizeof(Tokenlist);
+ Tokenlist *tokens = (Tokenlist *)malloc(tokensSize);
+ if (!stak || !tokens) {
+ free(stak);
+ free(tokens);
+
+ error("[DecompressorLZW::unpackLZW1] Cannot allocate decompression buffers");
+ }
+
+ memset(tokens, 0, tokensSize);
+
byte lastchar = 0;
uint16 stakptr = 0, lastbits = 0;
- Tokenlist tokens[0x1004];
- memset(tokens, 0, sizeof(tokens));
-
byte decryptstart = 0;
uint16 bitstring;
@@ -310,6 +336,10 @@ int DecompressorLZW::unpackLZW1(Common::ReadStream *src, byte *dest, uint32 nPac
break;
}
}
+
+ free(stak);
+ free(tokens);
+
return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
}
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 100b71efa7..2285e512bd 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -23,6 +23,7 @@
#include "engines/advancedDetector.h"
#include "base/plugins.h"
#include "common/file.h"
+#include "common/ptr.h"
#include "common/savefile.h"
#include "common/system.h"
#include "graphics/thumbnail.h"
@@ -224,6 +225,7 @@ static const OldNewIdTableEntry s_oldNewTable[] = {
{ "emc", "funseeker", SCI_VERSION_NONE },
{ "gk", "gk1", SCI_VERSION_NONE },
// gk2 is the same
+ { "gk2demo", "gk2", SCI_VERSION_NONE },
{ "hoyledemo", "hoyle1", SCI_VERSION_NONE },
{ "cardgames", "hoyle1", SCI_VERSION_NONE },
{ "solitare", "hoyle2", SCI_VERSION_NONE },
@@ -235,7 +237,7 @@ static const OldNewIdTableEntry s_oldNewTable[] = {
{ "kq4", "kq4sci", SCI_VERSION_NONE },
// kq5 is the same
// kq6 is the same
- // kq7 is the same
+ { "kq7cd", "kq7", SCI_VERSION_NONE },
{ "mm1", "laurabow", SCI_VERSION_NONE },
{ "cb1", "laurabow", SCI_VERSION_NONE },
{ "lb2", "laurabow2", SCI_VERSION_NONE },
@@ -323,7 +325,7 @@ Common::String convertSierraGameId(Common::String sierraId, uint32 *gameFlags, R
for (const OldNewIdTableEntry *cur = s_oldNewTable; cur->oldId[0]; ++cur) {
if (sierraId == cur->oldId) {
- // Distinguish same IDs from the SCI version
+ // Distinguish same IDs via the SCI version
if (cur->version != SCI_VERSION_NONE && cur->version != getSciVersion())
continue;
@@ -371,35 +373,11 @@ static ADGameDescription s_fallbackDesc = {
static char s_fallbackGameIdBuf[256];
-
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Sci::SciGameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- s_sciGameTitles,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "sci",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class SciMetaEngine : public AdvancedMetaEngine {
public:
- SciMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ SciMetaEngine() : AdvancedMetaEngine(Sci::SciGameDescriptions, sizeof(ADGameDescription), s_sciGameTitles) {
+ _singleid = "sci";
+ }
virtual const char *getName() const {
return "SCI [SCI0, SCI01, SCI10, SCI11"
@@ -414,7 +392,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
- const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const;
+ const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
virtual bool hasFeature(MetaEngineFeature f) const;
virtual SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
@@ -442,7 +420,7 @@ Common::Language charToScummVMLanguage(const char c) {
}
}
-const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
+const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
bool foundResMap = false;
bool foundRes000 = false;
@@ -452,63 +430,57 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
s_fallbackDesc.flags = ADGF_NO_FLAGS;
s_fallbackDesc.platform = Common::kPlatformPC; // default to PC platform
s_fallbackDesc.gameid = "sci";
+ s_fallbackDesc.guioptions = Common::GUIO_NONE;
- // First grab all filenames
- for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
- if (file->isDirectory())
- continue;
-
- Common::String filename = file->getName();
- filename.toLowercase();
+ if (allFiles.contains("resource.map") || allFiles.contains("Data1")
+ || allFiles.contains("resmap.001") || allFiles.contains("resmap.001")) {
+ foundResMap = true;
+ }
- if (filename.contains("resource.map") || filename.contains("resmap.00") || filename.contains("Data1")) {
- foundResMap = true;
+ // Determine if we got a CD version and set the CD flag accordingly, by checking for
+ // resource.aud for SCI1.1 CD games, or audio001.002 for SCI1 CD games. We assume that
+ // the file should be over 10MB, as it contains all the game speech and is usually
+ // around 450MB+. The size check is for some floppy game versions like KQ6 floppy, which
+ // also have a small resource.aud file
+ if (allFiles.contains("resource.aud") || allFiles.contains("audio001.002")) {
+ Common::FSNode file = allFiles.contains("resource.aud") ? allFiles["resource.aud"] : allFiles["audio001.002"];
+ Common::SeekableReadStream *tmpStream = file.createReadStream();
+ if (tmpStream->size() > 10 * 1024 * 1024) {
+ // We got a CD version, so set the CD flag accordingly
+ s_fallbackDesc.flags |= ADGF_CD;
}
+ delete tmpStream;
+ }
- // Determine if we got a CD version and set the CD flag accordingly, by checking for
- // resource.aud for SCI1.1 CD games, or audio001.002 for SCI1 CD games. We assume that
- // the file should be over 10MB, as it contains all the game speech and is usually
- // around 450MB+. The size check is for some floppy game versions like KQ6 floppy, which
- // also have a small resource.aud file
- if (filename.contains("resource.aud") || filename.contains("audio001.002")) {
- Common::SeekableReadStream *tmpStream = file->createReadStream();
- if (tmpStream->size() > 10 * 1024 * 1024) {
- // We got a CD version, so set the CD flag accordingly
- s_fallbackDesc.flags |= ADGF_CD;
- s_fallbackDesc.extra = "CD";
- }
- delete tmpStream;
- }
+ if (allFiles.contains("resource.000") || allFiles.contains("resource.001")
+ || allFiles.contains("ressci.000") || allFiles.contains("ressci.001"))
+ foundRes000 = true;
- if (filename.contains("resource.000") || filename.contains("resource.001")
- || filename.contains("ressci.000") || filename.contains("ressci.001"))
- foundRes000 = true;
+ // Data1 contains both map and volume for SCI1.1+ Mac games
+ if (allFiles.contains("Data1")) {
+ foundResMap = foundRes000 = true;
+ s_fallbackDesc.platform = Common::kPlatformMacintosh;
+ }
- // Data1 contains both map and volume for SCI1.1+ Mac games
- if (filename.contains("Data1")) {
- foundResMap = foundRes000 = true;
- s_fallbackDesc.platform = Common::kPlatformMacintosh;
- }
+ // Determine the game platform
+ // The existence of any of these files indicates an Amiga game
+ if (allFiles.contains("9.pat") || allFiles.contains("spal") ||
+ allFiles.contains("patch.005") || allFiles.contains("bank.001"))
+ s_fallbackDesc.platform = Common::kPlatformAmiga;
- // Determine the game platform
- // The existence of any of these files indicates an Amiga game
- if (filename.contains("9.pat") || filename.contains("spal") ||
- filename.contains("patch.005") || filename.contains("bank.001"))
- s_fallbackDesc.platform = Common::kPlatformAmiga;
+ // The existence of 7.pat or patch.200 indicates a Mac game
+ if (allFiles.contains("7.pat") || allFiles.contains("patch.200"))
+ s_fallbackDesc.platform = Common::kPlatformMacintosh;
- // The existence of 7.pat or patch.200 indicates a Mac game
- if (filename.contains("7.pat") || filename.contains("patch.200"))
- s_fallbackDesc.platform = Common::kPlatformMacintosh;
+ // The data files for Atari ST versions are the same as their DOS counterparts
- // The data files for Atari ST versions are the same as their DOS counterparts
- }
// If these files aren't found, it can't be SCI
if (!foundResMap && !foundRes000) {
return 0;
}
- ResourceManager *resMan = new ResourceManager();
+ Common::ScopedPtr<ResourceManager> resMan(new ResourceManager());
assert(resMan);
resMan->addAppropriateSources(fslist);
resMan->init(true);
@@ -518,7 +490,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
// Is SCI32 compiled in? If not, and this is a SCI32 game,
// stop here
if (getSciVersion() >= SCI_VERSION_2) {
- delete resMan;
return (const ADGameDescription *)&s_fallbackDesc;
}
#endif
@@ -529,7 +500,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
// Can't be SCI (or unsupported SCI views). Pinball Creep by sierra also uses resource.map/resource.000 files
// but doesnt share sci format at all, if we dont return 0 here we will detect this game as SCI
if (gameViews == kViewUnknown) {
- delete resMan;
return 0;
}
@@ -542,7 +512,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
// If we don't have a game id, the game is not SCI
if (sierraGameId.empty()) {
- delete resMan;
return 0;
}
@@ -581,24 +550,43 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
}
- // Fill in extras field
+ // Fill in "extra" field
+
+ // Is this an EGA version that might have a VGA pendant? Then we want
+ // to mark it as such in the "extra" field.
+ const bool markAsEGA = (gameViews == kViewEga && s_fallbackDesc.platform != Common::kPlatformAmiga
+ && getSciVersion() > SCI_VERSION_1_EGA_ONLY);
+
+ const bool isDemo = (s_fallbackDesc.flags & ADGF_DEMO);
+ const bool isCD = (s_fallbackDesc.flags & ADGF_CD);
+
+ if (!isCD)
+ s_fallbackDesc.guioptions |= Common::GUIO_NOSPEECH;
if (gameId.hasSuffix("sci")) {
s_fallbackDesc.extra = "SCI";
// Differentiate EGA versions from the VGA ones, where needed
- if (gameViews == kViewEga && s_fallbackDesc.platform != Common::kPlatformAmiga)
+ if (markAsEGA)
s_fallbackDesc.extra = "SCI/EGA";
+
+ // Mark as demo.
+ // Note: This overwrites the 'EGA' info, if it was previously set.
+ if (isDemo)
+ s_fallbackDesc.extra = "SCI/Demo";
} else {
- if (gameViews == kViewEga && s_fallbackDesc.platform != Common::kPlatformAmiga)
+ if (markAsEGA)
s_fallbackDesc.extra = "EGA";
- }
- // Add "demo" to the description for demos
- if (s_fallbackDesc.flags & ADGF_DEMO)
- s_fallbackDesc.extra = (gameId.hasSuffix("sci")) ? "SCI/Demo" : "Demo";
-
- delete resMan;
+ // Set "CD" and "Demo" as appropriate.
+ // Note: This overwrites the 'EGA' info, if it was previously set.
+ if (isDemo && isCD)
+ s_fallbackDesc.extra = "CD Demo";
+ else if (isDemo)
+ s_fallbackDesc.extra = "Demo";
+ else if (isCD)
+ s_fallbackDesc.extra = "CD";
+ }
return (const ADGameDescription *)&s_fallbackDesc;
}
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index d56d8f03cd..6641f243e6 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -60,7 +60,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH },
- // Castle of Dr. Brain - German Amiga (from www.back2roots.org, also includes english language)
+ // Castle of Dr. Brain - German Amiga (from www.back2roots.org, also includes English language)
// Executable scanning reports "1.005.001"
// SCI interpreter version 1.000.510
{"castlebrain", "", {
@@ -72,6 +72,16 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH },
+ // Castle of Dr. Brain Macintosh (from omer_mor, bug report #3328251)
+ {"castlebrain", "", {
+ {"resource.map", 0, "75cb06a94d2e0641295edd043f26f3a8", 2763},
+ {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 476566},
+ {"resource.001", 0, "7f7da982f5cd868e1e608cd4f6515656", 400521},
+ {"resource.002", 0, "e1a6b6f1060f60be9dcb6d28ad7a2a20", 1168310},
+ {"resource.003", 0, "6c3d1bb26ad532c94046bc9ac49b5ff4", 891295},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH },
+
// Castle of Dr. Brain - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.005
{"castlebrain", "Demo", {
@@ -503,6 +513,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ // Eco Quest 2 - Spanish DOS Floppy (supplied by umbrio in bug report #3313962)
+ {"ecoquest2", "Floppy", {
+ {"resource.map", 0, "a6b271b934afa7e84d03816a4fefa67b", 5593},
+ {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4209150},
+ {"resource.msg", 0, "eff8be1925d42288de55e405983e9314", 117810},
+ AD_LISTEND},
+ Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+
// Freddy Pharkas - English DOS demo (from FRG)
// SCI interpreter version 1.001.069
{"freddypharkas", "Demo", {
@@ -609,7 +627,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Gabriel Knight - English DOS Floppy (supplied my markcoolio in bug report #2723777)
// SCI interpreter version 2.000.000
@@ -617,7 +635,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// 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"
@@ -625,7 +643,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ef41df08cf2c1f680216cdbeed0f8311", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Gabriel Knight - German DOS Floppy (supplied my markcoolio in bug report #2723775)
// SCI interpreter version 2.000.000
@@ -633,7 +651,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Gabriel Knight - English DOS CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "01.100.000"
@@ -641,7 +659,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight - English Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "01.100.000"
@@ -649,7 +667,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, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight - German DOS CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -657,7 +675,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_CD, GUIO_NONE },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight - Spanish DOS CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -665,7 +683,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO_NONE },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight - French DOS CD (from Hkz)
// VERSION file reports "1.000.000, May 3, 1994"
@@ -673,7 +691,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "55f909ba93a2515042a08d8a2da8414e", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13325145},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, ADGF_CD, GUIO_NONE },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight - German Windows CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -681,7 +699,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, GUIO_NONE },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight - Spanish Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -689,7 +707,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, GUIO_NONE },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight - English Macintosh
{"gk1", "", {
@@ -698,7 +716,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data3", 0, "f25068b408b09275d8b698866462f578", 3677599},
{"Data4", 0, "1cceebbe411b26c860a74f91c337fdf3", 3230086},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO_NONE },
// Gabriel Knight 2 - English Windows Non-Interactive Demo
// Executable scanning reports "2.100.002"
@@ -706,7 +724,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, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
// Gabriel Knight 2 - English DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.1"
@@ -724,7 +742,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977},
{"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Gabriel Knight 2 - French DOS (6-CDs Sierra Originals reedition)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -742,7 +760,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "11b2e722170b8c93fdaa5428e2c7676f", 3001},
{"ressci.006", 0, "4037d941aec39d2e654e20960429aefc", 60568486},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, 0,
+ Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE,
GUIO_NOSPEECH },
// Gabriel Knight 2 - English Macintosh
@@ -755,7 +773,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data4", 0, "8b843c62eb53136a855d6e0087e3cb0d", 5889553},
{"Data5", 0, "f9fcf9ab2eb13b2125c33a1cda03a093", 14349984},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO_NONE },
#endif // ENABLE_SCI32
@@ -1438,7 +1456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195},
{"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// King's Quest 7 - English Windows (from the King's Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.4"
@@ -1446,7 +1464,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// King's Quest 7 - English DOS (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1454,7 +1472,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// King's Quest 7 - English Windows (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1462,7 +1480,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402)
// SCI interpreter version 2.100.002
@@ -1470,7 +1488,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// King's Quest 7 - Spanish DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "2.00"
@@ -1478,7 +1496,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// King's Quest 7 - English DOS Non-Interactive Demo
// SCI interpreter version 2.100.002
@@ -1486,7 +1504,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690},
{"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
#endif // ENABLE_SCI32
@@ -1652,6 +1670,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ // Larry 1 VGA Remake - English Macintosh (from omer_mor, bug report #3328262)
+ {"lsl1sci", "SCI", {
+ {"resource.map", 0, "6395e7f7881e37e39d81ff5175a35f6f", 3237},
+ {"resource.000", 0, "5933df4ea688584d6f59fdea5a9404f8", 989066},
+ {"resource.001", 0, "aa6f153f70f1e32d1bde465fff08eecf", 1137418},
+ {"resource.002", 0, "b22c616aa789ebef990290c7ffd86548", 1097477},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH },
+
// Larry 1 VGA Remake - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.084
{"lsl1sci", "SCI/Demo", {
@@ -1915,6 +1942,20 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ // Larry 5 - English Macintosh (from omer_mor, bug report #3328257)
+ {"lsl5", "", {
+ {"resource.map", 0, "f12439da78b9878e16436661deb83f84", 6525},
+ {"resource.000", 0, "f2537473213d70e7f4fc82e988ab90ca", 702403},
+ {"resource.001", 0, "db4a1381d88028876a99303bfaaba893", 704679},
+ {"resource.002", 0, "e86aeb27711f4a673e06ec32cfc84125", 1125854},
+ {"resource.003", 0, "13fd4942bb818f9acd2970d66fca6509", 854733},
+ {"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 1046644},
+ {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 1008293},
+ {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1110043},
+ {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 989801},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH },
+
// Larry 5 - German DOS (from Tobis87)
// SCI interpreter version T.A00.196
{"lsl5", "", {
@@ -2079,7 +2120,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872},
{"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
// Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2087,7 +2128,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
// Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2095,7 +2136,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
// Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2103,7 +2144,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878},
{"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
#ifdef ENABLE_SCI3_GAMES
// Larry 7 - English DOS CD (from spookypeanut)
@@ -2112,7 +2153,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188},
{"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
// Larry 7 - German DOS (from Tobis87)
// SCI interpreter version 3.000.000
@@ -2120,7 +2161,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188},
{"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Larry 7 - French DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 3.000.000
@@ -2128,7 +2169,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206},
{"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Larry 7 - Italian DOS CD (from glorifindel)
// SCI interpreter version 3.000.000
@@ -2136,7 +2177,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212},
{"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::IT_ITA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
// Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "3.000.000", VERSION file reports "1.0s"
@@ -2144,7 +2185,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188},
{"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
#endif
// Lighthouse - English Windows Demo (from jvprat)
@@ -2153,7 +2194,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64},
{"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
#ifdef ENABLE_SCI3_GAMES
// Lighthouse - English Windows Demo
@@ -2162,7 +2203,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525},
{"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
// Lighthouse - English DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2172,7 +2213,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573},
{"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Lighthouse - Spanish DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2182,7 +2223,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630},
{"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2299,7 +2340,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741},
{"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
// Mixed-Up Mother Goose Deluxe - Multilingual Windows CD (English/French/German/Spanish)
// Executable scanning reports "2.100.002"
@@ -2307,7 +2348,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "ef611af561898dcfea87846919ebf3eb", 4969},
{"ressci.000", 0, "227685bc59d90821978d330713e44a7a", 17205800},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
#endif // ENABLE_SCI32
// Ms. Astro Chicken - English DOS
@@ -2337,15 +2378,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972},
//{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
-
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
+
// Phantasmagoria - English DOS Demo
// Executable scanning reports "2.100.002"
{"phantasmagoria", "Demo", {
{"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518},
{"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
// Phantasmagoria - English DOS/Windows (GOG version) - ressci.* merged in ressci.000
// Windows executable scanning reports "2.100.002" - "Sep 19 1995 15:09:43"
@@ -2356,7 +2397,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "cd5967f9b9586e3380645961c0765be3", 116822037},
{"resmap.000", 0, "3cafc1c6a53945c1f3babbfd6380c64c", 16468},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Phantasmagoria - English Macintosh
// NOTE: This only contains disc 1 files (as well as the two persistent files:
@@ -2372,7 +2413,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
// Data8-12 are empty
{"Data13", 0, "6d2c450fca19a69b5af74ed5b03c0a17", 14923328},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO_NONE },
#ifdef ENABLE_SCI3_GAMES
// Phantasmagoria 2 - English Windows (from jvprat)
@@ -2389,7 +2430,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942},
{"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Phantasmagoria 2 - English DOS (GOG version) - ressci.* merged in ressci.000
// Executable scanning reports "3.000.000" - "Dec 07 1996 09:29:03"
@@ -2399,7 +2440,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "c54f26d9f43f908151263254b6d97053", 108134481},
{"resmap.000", 0, "de154a223a9ef4ea7358b76adc38ef5b", 2956},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2606,7 +2647,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374},
{"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Police Quest 4 - English DOS
// SCI interpreter version 2.000.000 (a guess?)
@@ -2614,7 +2655,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895},
{"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Police Quest 4 - French DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 2.000.000
@@ -2622,7 +2663,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "008030846edcc7c5c7a812c7f4ae4ceb", 9256},
{"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730153},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Police Quest 4 - German DOS (supplied by markcoolio in bug report #2723840)
// SCI interpreter version 2.000.000 (a guess?)
@@ -2630,7 +2671,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256},
{"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Police Quest: SWAT - English DOS/Windows Demo (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "0.001.200"
@@ -2638,7 +2679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648},
{"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
// Police Quest: SWAT - English DOS (from GOG.com)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2646,7 +2687,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "1c2563fee189885e29d9348f37306d94", 12175},
{"ressci.000", 0, "b2e1826ca81ce2e7e764587f5a14eee9", 127149181},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE },
// Police Quest: SWAT - English Windows (from the Police Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2661,7 +2702,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.004", 0, "4228038906f041623e65789500b22285", 6835},
{"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE },
#endif // ENABLE_SCI32
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784)
@@ -2972,7 +3013,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301},
{"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Quest for Glory 4 1.1 Floppy - English DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 2.000.000
@@ -2980,7 +3021,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d10a4cc177d2091d744e2ad8c049b0ae", 9295},
{"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11003589},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// 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"
@@ -2988,7 +3029,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301},
{"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Quest for Glory 4 CD - English DOS/Windows (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -2996,7 +3037,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246},
{"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// RAMA - English DOS/Windows Demo
// Executable scanning reports "2.100.002", VERSION file reports "000.000.008"
@@ -3004,7 +3045,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, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NONE },
#ifdef ENABLE_SCI3_GAMES
// RAMA - English Windows (from jvprat)
@@ -3017,7 +3058,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE },
// RAMA - English Windows (from Quietust, in bug report #2850645)
{"rama", "", {
@@ -3028,7 +3069,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "48841e4b84ef1b98b48d43566fda9e13", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6870356},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE },
// RAMA - Italian Windows CD (from glorifindel)
// SCI interpreter version 3.000.000 (a guess?)
@@ -3036,7 +3077,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091},
{"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE },
#endif // ENABLE_SCI3_GAMES
// Shivers - English Windows (from jvprat)
@@ -3045,14 +3086,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525},
{"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE },
// Shivers - German Windows (from Tobis87)
{"shivers", "", {
{"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537},
{"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NONE },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE },
// Shivers - English Windows Demo
// Executable scanning reports "2.100.002"
@@ -3060,7 +3101,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, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NONE },
// Shivers 2 doesn't contain SCI scripts. The whole game logic has
// been reimplemented from SCI in native code placed in DLL files.
@@ -3078,7 +3119,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, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NONE },
// Shivers 2 - English Windows (from abevi)
// VERSION.TXT Version 1.0 (3/25/97)
@@ -3086,7 +3127,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "a79d03d6eb75be0a79324f14e3d2ace4", 95346793},
{"resmap.001", 0, "a4804d436d90c4ec2e46b537f5e954db", 6268},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
#endif
@@ -3471,7 +3512,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
// Space Quest 4 - English Macintosh
// Executable scanning reports "x.yyy.zzz"
- // VERSION file reports "1.148"
+ // VERSION file reports "1.148"
{"sq4", "", {
{"resource.map", 0, "6ffc6f76c4127d140759a512ab9a07be", 6042},
{"resource.000", 0, "6a538b389705232cf9b2d7de2cf9c0a7", 224833},
@@ -3564,7 +3605,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3572,7 +3613,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// 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"
@@ -3580,7 +3621,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "3c831625931d5079b73ae8c275f52c95", 10534},
{"resource.000", 0, "4195ca940f759424f62b90e262cc1737", 40932397},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3588,7 +3629,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534},
{"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE },
// Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3596,7 +3637,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572},
{"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
#endif // ENABLE_SCI32
// The Island of Dr. Brain - English DOS CD (from jvprat)
@@ -3630,7 +3671,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, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH },
// Torin's Passage - English Windows
// SCI interpreter version 2.100.002 (just a guess)
@@ -3638,7 +3679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Torin's Passage - Spanish Windows (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3647,7 +3688,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, 0, GUIO_NOSPEECH },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Torin's Passage - French Windows
// SCI interpreter version 2.100.002 (just a guess)
@@ -3655,7 +3696,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Torin's Passage - German Windows
// SCI interpreter version 2.100.002 (just a guess)
@@ -3663,7 +3704,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH },
// Torin's Passage - Italian Windows CD (from glorifindel)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3671,7 +3712,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE },
#endif // ENABLE_SCI32
// SCI Fanmade Games
diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h
index 07ba626d15..4592c5be9c 100644
--- a/engines/sci/engine/features.h
+++ b/engines/sci/engine/features.h
@@ -75,7 +75,7 @@ public:
* @return Message function type, SCI_VERSION_1_LATE / SCI_VERSION_1_1
*/
SciVersion detectMessageFunctionType();
-
+
#ifdef ENABLE_SCI32
/**
* Autodetects the kernel functions used in SCI2.1
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 68b1601580..ff3c67c84b 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -272,7 +272,7 @@ private:
// Kernel-related lists
Common::StringArray _selectorNames;
Common::StringArray _kernelNames;
-
+
const Common::String _invalid;
};
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 31ef64d109..0c5d4e680d 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -558,16 +558,16 @@ static SciKernelMapEntry s_kernelMap[] = {
// SetWindowsOption is used to set Windows specific options, like for example the title bar visibility of
// the game window in Phantasmagoria 2. We ignore these settings completely.
{ MAP_EMPTY(SetWindowsOption), SIG_EVERYWHERE, "ii", NULL, NULL },
-
+
// Used by the Windows version of Phantasmagoria 1 to get the video speed setting. This is called after
- // kGetConfig and overrides the setting obtained by it. It is a dummy function in the DOS Version. We can
+ // kGetConfig and overrides the setting obtained by it. It is a dummy function in the DOS Version. We can
// just use GetConfig and mark this one as empty, like the DOS version does.
{ MAP_EMPTY(GetSierraProfileInt), SIG_EVERYWHERE, "(.*)", NULL, NULL },
// Unused / debug SCI2.1 unused functions, always mapped to kDummy
// The debug functions are called from the inbuilt debugger or polygon
- // editor in SCI2.1 games. Related objects are: PEditor, EditablePolygon,
+ // editor in SCI2.1 games. Related objects are: PEditor, EditablePolygon,
// aeDisplayClass and scalerCode
{ MAP_DUMMY(FindSelector), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_DUMMY(FindClass), SIG_EVERYWHERE, "(.*)", NULL, NULL },
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index 2cd6b198de..df3b3efd57 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -194,7 +194,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
// Wait a bit here, so that the CPU isn't maxed out when the game
// is waiting for user input (e.g. when showing text boxes) - bug
// #3037874. Make sure that we're not delaying while the game is
- // benchmarking, as that will affect the final benchmarked result -
+ // benchmarking, as that will affect the final benchmarked result -
// check bugs #3058865 and #3127824
if (s->_gameIsBenchmarking) {
// Game is benchmarking, don't add a delay
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index e1e52215d2..1bd6754ca5 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -208,7 +208,7 @@ reg_t kFClose(EngineState *s, int argc, reg_t *argv) {
reg_t kFPuts(EngineState *s, int argc, reg_t *argv) {
int handle = argv[0].toUint16();
Common::String data = s->_segMan->getString(argv[1]);
-
+
FileHandle *f = getFileFromHandle(s, handle);
if (f)
f->_out->write(data.c_str(), data.size());
@@ -812,7 +812,7 @@ reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) {
int bytesRead = 0;
char *buf = new char[size];
debugC(kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size);
-
+
FileHandle *f = getFileFromHandle(s, handle);
if (f) {
bytesRead = f->_in->read(buf, size);
@@ -910,7 +910,7 @@ reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) {
int offset = argv[1].toUint16();
int whence = argv[2].toUint16();
debugC(kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence);
-
+
FileHandle *f = getFileFromHandle(s, handle);
if (f)
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 6c96266922..36de767464 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -151,7 +151,7 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) {
case 2:
pos.y = argv[1].toSint16();
pos.x = argv[0].toSint16();
-
+
g_sci->_gfxCursor->kernelSetPos(pos);
break;
case 4: {
@@ -192,7 +192,7 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) {
break;
case 10:
// Freddy pharkas, when using the whiskey glass to read the prescription (bug #3034973)
- g_sci->_gfxCursor->kernelSetZoomZone(argv[0].toUint16(),
+ g_sci->_gfxCursor->kernelSetZoomZone(argv[0].toUint16(),
Common::Rect(argv[1].toUint16(), argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16()),
argv[5].toUint16(), argv[6].toUint16(), argv[7].toUint16(),
argv[8].toUint16(), argv[9].toUint16());
@@ -428,7 +428,7 @@ reg_t kCanBeHere(EngineState *s, int argc, reg_t *argv) {
reg_t kCantBeHere(EngineState *s, int argc, reg_t *argv) {
reg_t curObject = argv[0];
reg_t listReference = (argc > 1) ? argv[1] : NULL_REG;
-
+
reg_t canBeHere = g_sci->_gfxCompare->kernelCanBeHere(curObject, listReference);
return canBeHere;
}
@@ -1279,7 +1279,7 @@ reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv) {
// TODO
// reg_t curObject = argv[0];
// reg_t listReference = (argc > 1) ? argv[1] : NULL_REG;
-
+
return NULL_REG;
}
@@ -1642,8 +1642,8 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) {
reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) {
// TODO: This defines the resolution that the fonts are supposed to be displayed
// in. Currently, this is only used for showing high-res fonts in GK1 Mac, but
- // should be extended to handle other font resolutions such as those
-
+ // should be extended to handle other font resolutions such as those
+
int xResolution = argv[0].toUint16();
//int yResolution = argv[1].toUint16();
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index daed248db1..e6837242e4 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -75,11 +75,11 @@ reg_t kGameIsRestarting(EngineState *s, int argc, reg_t *argv) {
}
break;
case GID_SQ4:
- // In SQ4 (floppy and CD) the sequel police appear way too quickly in
+ // In SQ4 (floppy and CD) the sequel police appear way too quickly in
// the Skate-o-rama rooms, resulting in all sorts of timer issues, like
// #3109139 (which occurs because a police officer instantly teleports
// just before Roger exits and shoots him). We throttle these scenes a
- // bit more, in order to prevent timer bugs related to the sequel police
+ // bit more, in order to prevent timer bugs related to the sequel police
if (s->currentRoomNumber() == 405 || s->currentRoomNumber() == 406 ||
s->currentRoomNumber() == 410 || s->currentRoomNumber() == 411) {
s->_throttleTrigger = true;
@@ -186,7 +186,7 @@ reg_t kSetDebug(EngineState *s, int argc, reg_t *argv) {
if (g_sci->getGameId() != GID_GK1) {
debug("Debug mode activated");
-
+
g_sci->getDebugger()->attach();
}
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index 31715f19d3..14f7db47a0 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -239,7 +239,7 @@ reg_t kInitBresen(EngineState *s, int argc, reg_t *argv) {
client_step--;
if (!client_step)
- error("kInitBresen failed");
+ error("kInitBresen failed");
client_xStep--;
}
@@ -440,7 +440,7 @@ reg_t kDoAvoider(EngineState *s, int argc, reg_t *argv) {
invokeSelector(s, clientLooper, SELECTOR(doit), argc, argv, 2, params);
}
s->r_acc = SIGNAL_REG;
-
+
} else {
// is blocked
if (avoiderHeading == -1)
diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp
index 8904a48978..375aeaa06b 100644
--- a/engines/sci/engine/kpathing.cpp
+++ b/engines/sci/engine/kpathing.cpp
@@ -1110,7 +1110,7 @@ static Polygon *convert_polygon(EngineState *s, reg_t polygon) {
// Make sure that we have enough points
if (pointList.maxSize < size * POLY_POINT_SIZE) {
warning("convert_polygon: Not enough memory allocated for polygon points. "
- "Expected %d, got %d. Skipping polygon",
+ "Expected %d, got %d. Skipping polygon",
size * POLY_POINT_SIZE, pointList.maxSize);
return NULL;
}
@@ -1202,7 +1202,7 @@ static PathfindingState *convert_polygon_set(EngineState *s, reg_t poly_list, Co
change_polygons_opt_0(pf_s);
Common::Point *new_start = fixup_start_point(pf_s, start);
-
+
if (!new_start) {
warning("AvoidPath: Couldn't fixup start position for pathfinding");
delete pf_s;
@@ -1210,7 +1210,7 @@ static PathfindingState *convert_polygon_set(EngineState *s, reg_t poly_list, Co
}
Common::Point *new_end = fixup_end_point(pf_s, end);
-
+
if (!new_end) {
warning("AvoidPath: Couldn't fixup end position for pathfinding");
delete new_start;
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index d83254b2c4..93c1fffe3c 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -163,7 +163,7 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
// extend the internal storage size.
if (infoSelector & kInfoFlagClone)
parentObj = s->_segMan->getObject(parentAddr);
-
+
*cloneObj = *parentObj;
// Mark as clone
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index c3c10bd2a2..9f10691767 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -238,14 +238,14 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
/* int writelength; -- unused atm */
- if (xfer && (isdigit(xfer) || xfer == '-' || xfer == '=')) {
+ if (xfer && (isdigit(static_cast<unsigned char>(xfer)) || xfer == '-' || xfer == '=')) {
char *destp;
if (xfer == '0')
fillchar = '0';
else if (xfer == '=')
align = ALIGN_CENTER;
- else if (isdigit(xfer) || (xfer == '-'))
+ else if (isdigit(static_cast<unsigned char>(xfer)) || (xfer == '-'))
source--; // Go to start of length argument
str_leng = strtol(source, &destp, 10);
@@ -427,7 +427,7 @@ reg_t kGetFarText(EngineState *s, int argc, reg_t *argv) {
}
seeker = (char *)textres->data;
-
+
// The second parameter (counter) determines the number of the string
// inside the text resource.
while (counter--) {
@@ -715,7 +715,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
// triggers an assert when doing string2[i + index2].
for (uint16 i = 0; i < count; i++)
string1->setValue(i + index1, string2[i + index2]);
-
+
return strAddress;
}
case 7: { // Cmp
@@ -781,14 +781,14 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
return NULL_REG;
case 15: { // upper
Common::String string = s->_segMan->getString(argv[1]);
-
+
string.toUppercase();
s->_segMan->strcpy(argv[1], string.c_str());
return NULL_REG;
}
case 16: { // lower
Common::String string = s->_segMan->getString(argv[1]);
-
+
string.toLowercase();
s->_segMan->strcpy(argv[1], string.c_str());
return NULL_REG;
diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index 9a60f39c85..6d810d516c 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -65,7 +65,7 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) {
scaleBuffer = new byte[width * height * bytesPerPixel];
}
- uint16 x, y;
+ uint16 x, y;
// Sanity check...
if (videoState.x > 0 && videoState.y > 0 && isVMD) {
@@ -94,7 +94,7 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) {
if (frame) {
if (scaleBuffer) {
- // TODO: Probably should do aspect ratio correction in e.g. GK1 Windows
+ // 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_system->copyRectToScreen(scaleBuffer, pitch, x, y, width, height);
} else {
@@ -130,7 +130,7 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
uint16 screenWidth = g_system->getWidth();
uint16 screenHeight = g_system->getHeight();
-
+
Video::VideoDecoder *videoDecoder = 0;
if (argv[0].segment != 0) {
diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp
index f09f18298a..a1854a2723 100644
--- a/engines/sci/engine/object.cpp
+++ b/engines/sci/engine/object.cpp
@@ -259,13 +259,13 @@ void Object::initSelectorsSci3(const byte *buf) {
// two selectors are always reserved (because their storage
// space is used by the typeMask).
// We don't know beforehand how many methods and properties
- // there are, so we count them first.
+ // there are, so we count them first.
for (int groupNr = 0; groupNr < groups; ++groupNr) {
byte groupLocation = groupInfo[groupNr];
const byte *seeker = selectorBase + groupLocation * 32 * 2;
if (groupLocation != 0) {
- // This object actually has selectors belonging to this group
+ // This object actually has selectors belonging to this group
int typeMask = READ_SCI11ENDIAN_UINT32(seeker);
for (int bit = 2; bit < 32; ++bit) {
@@ -277,7 +277,7 @@ void Object::initSelectorsSci3(const byte *buf) {
} else {
// Undefined selector
}
-
+
}
}
}
@@ -296,7 +296,7 @@ void Object::initSelectorsSci3(const byte *buf) {
const byte *seeker = selectorBase + groupLocation * 32 * 2;
if (groupLocation != 0) {
- // This object actually has selectors belonging to this group
+ // This object actually has selectors belonging to this group
int typeMask = READ_SCI11ENDIAN_UINT32(seeker);
int groupBaseId = groupNr * 32;
@@ -323,7 +323,7 @@ void Object::initSelectorsSci3(const byte *buf) {
} else {
// Undefined selector
}
-
+
}
}
}
diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h
index 80c8e9e83d..0ca16b48a2 100644
--- a/engines/sci/engine/object.h
+++ b/engines/sci/engine/object.h
@@ -79,7 +79,7 @@ public:
}
reg_t getSpeciesSelector() const {
- if (getSciVersion() <= SCI_VERSION_2_1)
+ if (getSciVersion() <= SCI_VERSION_2_1)
return _variables[_offset];
else // SCI3
return _speciesSelectorSci3;
@@ -93,7 +93,7 @@ public:
}
reg_t getSuperClassSelector() const {
- if (getSciVersion() <= SCI_VERSION_2_1)
+ if (getSciVersion() <= SCI_VERSION_2_1)
return _variables[_offset + 1];
else // SCI3
return _superClassPosSci3;
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index fbd77eb076..1d899b0d37 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -51,7 +51,7 @@ struct EngineState;
* 19 - exportsAreWide
* 18 - SCI32 arrays/strings
* 17 - sound
- *
+ *
*/
enum {
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index a38aa06bc4..01e1afe5ea 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -160,7 +160,7 @@ void Script::load(ResourceManager *resMan) {
_numExports = 0;
_synonyms = 0;
_numSynonyms = 0;
-
+
if (getSciVersion() <= SCI_VERSION_1_LATE) {
_exportTable = (const uint16 *)findBlockSCI0(SCI_OBJ_EXPORTS);
if (_exportTable) {
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 2d3d8f6155..a714980a35 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -209,7 +209,7 @@ const byte ecoquest2SignatureEcorderTutorial[] = {
const uint16 ecoquest2PatchEcorderTutorial[] = {
0x31, 0x23, // bnt [next state] (save 1 byte)
- // The parameter count below should be 7, but we're out of bytes
+ // 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)
@@ -221,7 +221,7 @@ const uint16 ecoquest2PatchEcorderTutorial[] = {
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
+ // 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)
@@ -697,7 +697,7 @@ const SciScriptSignature laurabow2Signatures[] = {
// ===========================================================================
// Mother Goose SCI1/SCI1.1
-// MG::replay somewhat calculates the savedgame-id used when saving again
+// 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[] = {
@@ -1034,7 +1034,7 @@ const uint16 sq1vgaPatchEgoShowsCard[] = {
// script, description, magic DWORD, adjust
const SciScriptSignature sq1vgaSignatures[] = {
- { 58, "Sarien armory droid zapping ego first time", 1, PATCH_MAGICDWORD( 0x72, 0x88, 0x15, 0x36 ), -70,
+ { 58, "Sarien armory droid zapping ego first time", 1, PATCH_MAGICDWORD( 0x72, 0x88, 0x15, 0x36 ), -70,
sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
SCI_SIGNATUREENTRY_TERMINATOR};
@@ -1087,7 +1087,7 @@ void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scri
}
patch++;
patchWord = *patch;
- }
+ }
}
// will return -1 if no match was found, otherwise an offset to the start of the signature match
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 16098ab275..3a18fbc68f 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -72,7 +72,7 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
const byte *scr;
int scr_size;
reg_t retval = make_reg(pos.segment, pos.offset + 1);
- uint16 param_value = 0xffff; // Suppress GCC warning by setting default value, chose value as invalid to getKernelName etc.
+ uint16 param_value = 0xffff; // Suppress GCC warning by setting default value, chose value as invalid to getKernelName etc.
int i = 0;
Kernel *kernel = g_sci->getKernel();
@@ -174,13 +174,15 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
break;
case Script_SRelative:
- if (opsize)
- param_value = scr[retval.offset++];
+ if (opsize) {
+ int8 offset = (int8)scr[retval.offset++];
+ debugN(" %02x [%04x]", 0xff & offset, 0xffff & (retval.offset + offset));
+ }
else {
- param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]);
+ int16 offset = (int16)READ_SCI11ENDIAN_UINT16(&scr[retval.offset]);
retval.offset += 2;
+ debugN(" %04x [%04x]", 0xffff & offset, 0xffff & (retval.offset + offset));
}
- debugN(opsize ? " %02x [%04x]" : " %04x [%04x]", param_value, (0xffff) & (retval.offset + param_value));
break;
case Script_End:
@@ -615,8 +617,8 @@ void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr arg
Console *con = g_sci->getSciDebugger();
#ifdef VM_DEBUG_SEND
- debugN("Send to %04x:%04x (%s), selector %04x (%s):", PRINT_REG(send_obj),
- s->_segMan->getObjectName(send_obj), selector,
+ debugN("Send to %04x:%04x (%s), selector %04x (%s):", PRINT_REG(send_obj),
+ s->_segMan->getObjectName(send_obj), selector,
g_sci->getKernel()->getSelectorName(selector).c_str());
#endif // VM_DEBUG_SEND
@@ -642,18 +644,18 @@ void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr arg
reg_t selectorValue = *varp.getPointer(segMan);
if (!argc && (activeBreakpointTypes & BREAK_SELECTORREAD)) {
if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORREAD, send_obj, selector))
- con->DebugPrintf("Read from selector (%s:%s): %04x:%04x\n",
+ con->DebugPrintf("Read from selector (%s:%s): %04x:%04x\n",
objectName, selectorName,
PRINT_REG(selectorValue));
} else if (argc && (activeBreakpointTypes & BREAK_SELECTORWRITE)) {
if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORWRITE, send_obj, selector))
- con->DebugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
+ con->DebugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
objectName, selectorName,
PRINT_REG(selectorValue), PRINT_REG(argp[1]));
}
if (argc > 1)
- debug(kDebugLevelScripts, "Write to selector (%s:%s): change %04x:%04x to %04x:%04x, argc == %d\n",
+ debug(kDebugLevelScripts, "Write to selector (%s:%s): change %04x:%04x to %04x:%04x, argc == %d\n",
objectName, selectorName,
PRINT_REG(selectorValue), PRINT_REG(argp[1]), argc);
}
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 5d8a81a7f1..3f11d6ff49 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -255,7 +255,7 @@ SegmentRef ArrayTable::dereference(reg_t pointer) {
return ret;
}
-void ArrayTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
+void ArrayTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
_table[sub_addr.offset].destroy();
freeEntry(sub_addr.offset);
}
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 2edbea9676..c2f857f319 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -212,7 +212,7 @@ void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t
*address.getPointer(segMan) = value;
}
-void invokeSelector(EngineState *s, reg_t object, int selectorId,
+void invokeSelector(EngineState *s, reg_t object, int selectorId,
int k_argc, StackPtr k_argp, int argc, const reg_t *argv) {
int i;
int framesize = 2 + 1 * argc;
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index f13c13e00c..085dd6e832 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -185,7 +185,7 @@ void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t
/**
* Invokes a selector from an object.
*/
-void invokeSelector(EngineState *s, reg_t object, int selectorId,
+void invokeSelector(EngineState *s, reg_t object, int selectorId,
int k_argc, StackPtr k_argp, int argc = 0, const reg_t *argv = 0);
} // End of namespace Sci
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 3328f80de1..4ea9f72054 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -144,7 +144,7 @@ void EngineState::wait(int16 ticks) {
void EngineState::initGlobals() {
Script *script_000 = _segMan->getScript(1);
-
+
if (!script_000->_localsBlock)
error("Script 0 has no locals block");
@@ -331,7 +331,7 @@ void SciEngine::checkVocabularySwitch() {
uint16 parserLanguage = 1;
if (SELECTOR(parseLang) != -1)
parserLanguage = readSelectorValue(_gamestate->_segMan, _gameObjectAddress, SELECTOR(parseLang));
-
+
if (parserLanguage != _vocabularyLanguage) {
delete _vocabulary;
_vocabulary = new Vocabulary(_resMan, parserLanguage > 1 ? true : false);
diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp
index 6526eff2db..cca4c47be8 100644
--- a/engines/sci/engine/static_selectors.cpp
+++ b/engines/sci/engine/static_selectors.cpp
@@ -96,7 +96,7 @@ static const char * const sci2Selectors[] = {
"center", "all", "show", "textLeft", "textTop", // 115 - 119
"textRight", "textBottom", "borderColor", "titleFore", "titleBack", // 120 - 124
"titleFont", "dimmed", "frameOut", "lastKey", "magnifier", // 125 - 129
- "magPower", "mirrored", "pitch", "roll", "yaw", // 130 - 134
+ "magPower", "mirrored", "pitch", "roll", "yaw", // 130 - 134
"left", "right", "top", "bottom", "numLines" // 135 - 139
};
#endif
@@ -265,8 +265,8 @@ void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) {
if (targetClass) {
if (classReferences[i].selectorType == kSelectorMethod) {
if (targetClass->getMethodCount() < selectorOffset + 1)
- error("The %s class has less than %d methods (%d)",
- classReferences[i].className, selectorOffset + 1,
+ error("The %s class has less than %d methods (%d)",
+ classReferences[i].className, selectorOffset + 1,
targetClass->getMethodCount());
targetSelectorPos = targetClass->getFuncSelector(selectorOffset);
@@ -275,7 +275,7 @@ void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) {
selectorOffset += (getSciVersion() <= SCI_VERSION_1_LATE) ? 3 : 8;
if (targetClass->getVarCount() < selectorOffset + 1)
- error("The %s class has less than %d variables (%d)",
+ error("The %s class has less than %d variables (%d)",
classReferences[i].className, selectorOffset + 1,
targetClass->getVarCount());
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 499574957e..274b0bbbc9 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -42,7 +42,7 @@ const reg_t NULL_REG = {0, 0};
const reg_t SIGNAL_REG = {0, SIGNAL_OFFSET};
const reg_t TRUE_REG = {0, 1};
//#define VM_DEBUG_SEND
-// Enable the define below to have the VM abort on cases where a conditional
+// Enable the define below to have the VM abort on cases where a conditional
// statement is followed by an unconditional jump (which will most likely lead
// to an infinite loop). Aids in detecting script bugs such as #3040722.
//#define ABORT_ON_INFINITE_LOOP
@@ -130,16 +130,16 @@ static reg_t read_var(EngineState *s, int type, int index) {
if (solution.type == WORKAROUND_NONE) {
#ifdef RELEASE_BUILD
// If we are running an official ScummVM release -> fake 0 in unknown cases
- warning("Uninitialized read for temp %d from method %s::%s (script %d, room %d, localCall %x)",
- index, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr,
- g_sci->getEngineState()->currentRoomNumber(), originReply.localCallOffset);
+ warning("Uninitialized read for temp %d from method %s::%s (room %d, script %d, localCall %x)",
+ index, originReply.objectName.c_str(), originReply.methodName.c_str(), s->currentRoomNumber(),
+ originReply.scriptNr, originReply.localCallOffset);
s->variables[type][index] = NULL_REG;
break;
#else
- error("Uninitialized read for temp %d from method %s::%s (script %d, room %d, localCall %x)",
- index, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr,
- g_sci->getEngineState()->currentRoomNumber(), originReply.localCallOffset);
+ error("Uninitialized read for temp %d from method %s::%s (room %d, script %d, localCall %x)",
+ index, originReply.objectName.c_str(), originReply.methodName.c_str(), s->currentRoomNumber(),
+ originReply.scriptNr, originReply.localCallOffset);
#endif
}
assert(solution.type == WORKAROUND_FAKE);
@@ -366,9 +366,9 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
switch (solution.type) {
case WORKAROUND_NONE:
kernel->signatureDebug(kernelCall.signature, argc, argv);
- error("[VM] k%s[%x]: signature mismatch via method %s::%s (script %d, room %d, localCall 0x%x)",
- kernelCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(),
- originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset);
+ error("[VM] k%s[%x]: signature mismatch via method %s::%s (room %d, script %d, localCall 0x%x)",
+ kernelCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(),
+ s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
break;
case WORKAROUND_IGNORE: // don't do kernel call, leave acc alone
return;
@@ -418,13 +418,13 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
int callNameLen = strlen(kernelCall.name);
if (strncmp(kernelCall.name, kernelSubCall.name, callNameLen) == 0) {
const char *subCallName = kernelSubCall.name + callNameLen;
- error("[VM] k%s(%s): signature mismatch via method %s::%s (script %d, room %d, localCall %x)",
- kernelCall.name, subCallName, originReply.objectName.c_str(), originReply.methodName.c_str(),
- originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset);
+ error("[VM] k%s(%s): signature mismatch via method %s::%s (room %d, script %d, localCall %x)",
+ kernelCall.name, subCallName, originReply.objectName.c_str(), originReply.methodName.c_str(),
+ s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
}
- error("[VM] k%s: signature mismatch via method %s::%s (script %d, room %d, localCall %x)",
- kernelSubCall.name, originReply.objectName.c_str(), originReply.methodName.c_str(),
- originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset);
+ error("[VM] k%s: signature mismatch via method %s::%s (room %d, script %d, localCall %x)",
+ kernelSubCall.name, originReply.objectName.c_str(), originReply.methodName.c_str(),
+ s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
break;
}
case WORKAROUND_IGNORE: // don't do kernel call, leave acc alone
@@ -462,7 +462,7 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])
extOpcode = src[offset++]; // Get "extended" opcode (lower bit has special meaning)
const byte opcode = extOpcode >> 1; // get the actual opcode
- memset(opparams, 0, sizeof(opparams));
+ memset(opparams, 0, 4*sizeof(int16));
for (int i = 0; g_opcode_formats[opcode][i]; ++i) {
//debugN("Opcode: 0x%x, Opnumber: 0x%x, temp: %d\n", opcode, opcode, temp);
@@ -828,10 +828,10 @@ void run_vm(EngineState *s) {
uint16 localCallOffset = s->xs->addr.pc.offset + opparams[0];
- ExecStack xstack(s->xs->objp, s->xs->objp, s->xs->sp,
+ ExecStack xstack(s->xs->objp, s->xs->objp, s->xs->sp,
(call_base->requireUint16()) + s->r_rest, call_base,
s->xs->local_segment, make_reg(s->xs->addr.pc.segment, localCallOffset),
- NULL_SELECTOR, -1, localCallOffset, s->_executionStack.size() - 1,
+ NULL_SELECTOR, -1, localCallOffset, s->_executionStack.size() - 1,
EXEC_STACK_TYPE_CALL);
s->_executionStack.push_back(xstack);
diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp
index 71a28a9761..b95fd58129 100644
--- a/engines/sci/engine/vm_types.cpp
+++ b/engines/sci/engine/vm_types.cpp
@@ -32,9 +32,9 @@ reg_t reg_t::lookForWorkaround(const reg_t right) 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 (script %d, room %d, localCall %x)",
- PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
- originReply.methodName.c_str(), originReply.scriptNr, g_sci->getEngineState()->currentRoomNumber(),
+ 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(),
+ originReply.methodName.c_str(), g_sci->getEngineState()->currentRoomNumber(), originReply.scriptNr,
originReply.localCallOffset);
assert(solution.type == WORKAROUND_FAKE);
return make_reg(0, solution.value);
@@ -56,7 +56,7 @@ reg_t reg_t::operator+(const reg_t right) const {
return make_reg(segment, offset + right.toSint16());
default:
return lookForWorkaround(right);
- }
+ }
} else if (isNumber() && right.isPointer()) {
// Adding a pointer to a number, flip the order
return right + *this;
@@ -94,9 +94,9 @@ reg_t reg_t::operator/(const reg_t right) const {
reg_t reg_t::operator%(const reg_t right) const {
if (isNumber() && right.isNumber() && !right.isNull()) {
- // Support for negative numbers was added in Iceman, and perhaps in
+ // Support for negative numbers was added in Iceman, and perhaps in
// SCI0 0.000.685 and later. Theoretically, this wasn't really used
- // in SCI0, so the result is probably unpredictable. Such a case
+ // in SCI0, so the result is probably unpredictable. Such a case
// would indicate either a script bug, or a modulo on an unsigned
// integer larger than 32767. In any case, such a case should be
// investigated, instead of being silently accepted.
@@ -178,7 +178,7 @@ int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
if (treatAsUnsigned || !isNumber())
return toUint16() - right.toUint16();
else
- return toSint16() - right.toSint16();
+ return toSint16() - right.toSint16();
} else if (pointerComparisonWithInteger(right)) {
return 1;
} else if (right.pointerComparisonWithInteger(*this)) {
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 8bf90ff53d..e61da20f97 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -34,6 +34,7 @@ namespace Sci {
const SciWorkaroundEntry arithmeticWorkarounds[] = {
{ GID_CAMELOT, 92, 92, 0, "endingCartoon2", "changeState", 0x20d, 0, { WORKAROUND_FAKE, 0 } }, // op_lai: during the ending, sub gets called with no parameters, uses parameter 1 which is theGrail in this case - bug #3044734
{ GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xcc6, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when giving the papers to the customs officer, gets called against a pointer instead of a number - bug #3034464
+ { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xce0, 0, { WORKAROUND_FAKE, 0 } }, // Same as above, for the Spanish version - bug #3313962
{ GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_mul: The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #3038913
{ GID_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)
@@ -76,6 +77,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge
{ GID_HOYLE4, 300, 300, 0, "", "export 2", 0x1d4d, 0, { WORKAROUND_FAKE, 0 } }, // after passing around cards in hearts
{ GID_HOYLE4, 400, 400, 1, "GinHand", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Gin Rummy (e.g. when knocking and placing a card) - bug #3292334
+ { GID_HOYLE4, 500, 17, 1, "Character", "say", -1, 504, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Cribbage (e.g. when the opponent says "Last Card") - bug #3292327
{ GID_ISLANDBRAIN, 100, 937, 0, "IconBar", "dispatchEvent", -1, 58, { WORKAROUND_FAKE, 0 } }, // when using ENTER at the startup menu - bug #3045225
{ GID_ISLANDBRAIN, 140, 140, 0, "piece", "init", -1, 3, { WORKAROUND_FAKE, 1 } }, // first puzzle right at the start, some initialization variable. bnt is done on it, and it should be non-0
{ GID_ISLANDBRAIN, 200, 268, 0, "anElement", "select", -1, 0, { WORKAROUND_FAKE, 0 } }, // elements puzzle, gets used before super TextIcon
@@ -446,7 +448,7 @@ SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroun
do {
workaround = workaroundList;
while (workaround->methodName) {
- bool objectNameMatches = (workaround->objectName == NULL) ||
+ bool objectNameMatches = (workaround->objectName == NULL) ||
(workaround->objectName == g_sci->getSciLanguageString(searchObjectName, K_LANG_ENGLISH));
// Special case: in the fanmade Russian translation of SQ4, all
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index 74879f6c63..c14cfada07 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -261,7 +261,7 @@ SciEvent EventManager::getScummVMEvent() {
else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
input.character += 96; // 0x01 -> 'a'
}
-
+
// If no actual key was pressed (e.g. if only a modifier key was pressed),
// ignore the event
if (!input.character)
@@ -277,7 +277,7 @@ void EventManager::updateScreen() {
if (g_system->getMillis() - s->_screenUpdateTime >= 1000 / 60) {
g_system->updateScreen();
s->_screenUpdateTime = g_system->getMillis();
- // Throttle the checking of shouldQuit() to 60fps as well, since
+ // Throttle the checking of shouldQuit() to 60fps as well, since
// Engine::shouldQuit() invokes 2 virtual functions
// (EventManager::shouldQuit() and EventManager::shouldRTL()),
// which is very expensive to invoke constantly without any
diff --git a/engines/sci/graphics/animate.cpp b/engines/sci/graphics/animate.cpp
index c36ecd112a..18f8511953 100644
--- a/engines/sci/graphics/animate.cpp
+++ b/engines/sci/graphics/animate.cpp
@@ -201,7 +201,7 @@ void GfxAnimate::fill(byte &old_picNotValid) {
adjustInvalidCels(view, it);
processViewScaling(view, it);
setNsRect(view, it);
-
+
//warning("%s view %d, loop %d, cel %d, signal %x", _s->_segMan->getObjectName(curObject), it->viewId, it->loopNo, it->celNo, it->signal);
// Calculate current priority according to y-coordinate
@@ -659,7 +659,7 @@ void GfxAnimate::throttleSpeed() {
// No entries drawn -> no speed throttler triggering
break;
case 1: {
-
+
// One entry drawn -> check if that entry was a speed benchmark view, if not enable speed throttler
AnimateEntry *onlyCast = &_lastCastData[0];
if ((onlyCast->viewId == 0) && (onlyCast->loopNo == 13) && (onlyCast->celNo == 0)) {
diff --git a/engines/sci/graphics/compare.cpp b/engines/sci/graphics/compare.cpp
index 1dbe279f8a..3183ffa2b9 100644
--- a/engines/sci/graphics/compare.cpp
+++ b/engines/sci/graphics/compare.cpp
@@ -84,7 +84,14 @@ reg_t GfxCompare::canBeHereCheckRectList(reg_t checkObject, const Common::Rect &
curRect.right = readSelectorValue(_segMan, curObject, SELECTOR(brRight));
curRect.bottom = readSelectorValue(_segMan, curObject, SELECTOR(brBottom));
// Check if curRect is within checkRect
- if (checkRect.contains(curRect))
+ // This behavior is slightly odd, but it's how the original SCI
+ // engine did it: a rect cannot be contained within itself
+ // (there is no equality). Do NOT change this to contains(), as
+ // it breaks KQ4 early (bug #3315639).
+ if (curRect.right > checkRect.left &&
+ curRect.left < checkRect.right &&
+ curRect.bottom > checkRect.top &&
+ curRect.top < checkRect.bottom)
return curObject;
}
}
diff --git a/engines/sci/graphics/compare.h b/engines/sci/graphics/compare.h
index 83b4f49c08..bacb6e71e2 100644
--- a/engines/sci/graphics/compare.h
+++ b/engines/sci/graphics/compare.h
@@ -51,7 +51,7 @@ private:
GfxCoordAdjuster *_coordAdjuster;
uint16 isOnControl(uint16 screenMask, const Common::Rect &rect);
-
+
/**
* This function checks whether any of the objects in the given list,
* *different* from checkObject, has a brRect which is contained inside
diff --git a/engines/sci/graphics/controls.cpp b/engines/sci/graphics/controls.cpp
index 0289735c0a..8d4712a969 100644
--- a/engines/sci/graphics/controls.cpp
+++ b/engines/sci/graphics/controls.cpp
@@ -329,7 +329,6 @@ void GfxControls::kernelDrawText(Common::Rect rect, reg_t obj, const char *text,
if (style & SCI_CONTROLS_STYLE_SELECTED) {
_paint16->frameRect(rect);
}
- rect.grow(1);
if (!getPicNotValid())
_paint16->bitsShow(rect);
} else {
diff --git a/engines/sci/graphics/coordadjuster.h b/engines/sci/graphics/coordadjuster.h
index 1b8a3e2679..23cf79d209 100644
--- a/engines/sci/graphics/coordadjuster.h
+++ b/engines/sci/graphics/coordadjuster.h
@@ -68,7 +68,7 @@ public:
void moveCursor(Common::Point &pos);
Common::Rect pictureGetDisplayArea();
-
+
private:
GfxPorts *_ports;
@@ -90,7 +90,7 @@ public:
void pictureSetDisplayArea(Common::Rect displayArea);
Common::Rect pictureGetDisplayArea();
-
+
private:
SegManager *_segMan;
diff --git a/engines/sci/graphics/menu.cpp b/engines/sci/graphics/menu.cpp
index 9d4ab3f589..673729784f 100644
--- a/engines/sci/graphics/menu.cpp
+++ b/engines/sci/graphics/menu.cpp
@@ -423,7 +423,9 @@ reg_t GfxMenu::kernelSelect(reg_t eventObject, bool pauseSound) {
default:
while (itemIterator != itemEnd) {
itemEntry = *itemIterator;
- if ((itemEntry->keyPress == keyPress) && (itemEntry->keyModifier == keyModifier))
+ if (itemEntry->keyPress == keyPress &&
+ itemEntry->keyModifier == keyModifier &&
+ itemEntry->enabled)
break;
itemIterator++;
}
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 899ef10b33..c5a3545701 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -71,7 +71,7 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMergi
_macClut = 0;
loadMacIconBarPalette();
-
+
#ifdef ENABLE_SCI32
_clutTable = 0;
#endif
@@ -236,7 +236,7 @@ static byte blendColors(byte c1, byte c2) {
// return (c1/2+c2/2)+((c1&1)+(c2&1))/2;
// gamma 2.2
- double t = (pow(c1/255.0, 2.2/1.0) * 255.0) +
+ double t = (pow(c1/255.0, 2.2/1.0) * 255.0) +
(pow(c2/255.0, 2.2/1.0) * 255.0);
return (byte)(0.5 + (pow(0.5*t/255.0, 1.0/2.2) * 255.0));
}
@@ -378,7 +378,7 @@ bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) {
break;
}
}
-
+
// if still no luck - set an approximate color
if (j == 256) {
newPalette->mapping[i] = res & 0xFF;
@@ -991,7 +991,7 @@ void GfxPalette::unloadClut() {
delete[] _clutTable;
_clutTable = 0;
}
-
+
#endif
} // End of namespace Sci
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index 9b0c45baf6..243420cc47 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -125,7 +125,7 @@ private:
void loadMacIconBarPalette();
byte *_macClut;
-
+
#ifdef ENABLE_SCI32
byte *_clutTable;
#endif
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 6529a6ae64..ecb54e89e8 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -330,7 +330,7 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
if (!_addToFlag && _resourceType != SCI_PICTURE_TYPE_SCI32)
clearColor = _screen->getColorWhite();
- byte drawMask = priority == 255 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY;
+ byte drawMask = priority > 15 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY;
ptr = celBitmap;
ptr += skipCelBitmapPixels;
@@ -357,7 +357,7 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
curByte = *ptr++;
if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
_screen->putPixel(x, y, drawMask, curByte, priority, 0);
-
+
if (x == leftX) {
ptr += sourcePixelSkipPerRow;
x = rightX;
@@ -515,7 +515,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
icemanDrawFix = true;
}
if (g_sci->getGameId() == GID_KQ5) {
- // WORKAROUND: ignore the seemingly broken priority of picture 48
+ // WORKAROUND: ignore the seemingly broken priority of picture 48
// (island overview). Fixes bug #3041044.
if (_resourceId == 48)
ignoreBrokenPriority = true;
@@ -551,7 +551,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
case PIC_OP_SET_PRIORITY:
pic_priority = data[curPos++] & 0x0F;
- if (isEGA)
+ if (isEGA)
pic_priority = EGApriority[pic_priority];
if (ignoreBrokenPriority)
pic_priority = 255;
diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp
index 9412976d5b..6b4c8180bf 100644
--- a/engines/sci/graphics/ports.cpp
+++ b/engines/sci/graphics/ports.cpp
@@ -721,7 +721,7 @@ void GfxPorts::printWindowList(Console *con) {
if ((*it)->isWindow()) {
Window *wnd = ((Window *)*it);
con->DebugPrintf("%d: '%s' at %d, %d, (%d, %d, %d, %d), drawn: %d, style: %d\n",
- wnd->id, wnd->title.c_str(), wnd->left, wnd->top,
+ wnd->id, wnd->title.c_str(), wnd->left, wnd->top,
wnd->rect.left, wnd->rect.top, wnd->rect.right, wnd->rect.bottom,
wnd->bDrawn, wnd->wndStyle);
}
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index c2f71a0e54..84547d9828 100644
--- a/engines/sci/graphics/text16.cpp
+++ b/engines/sci/graphics/text16.cpp
@@ -100,7 +100,7 @@ int16 GfxText16::CodeProcessing(const char *&text, GuiResourceId orgFontId, int1
// cX -> sets textColor to _textColors[X-1]
curCode = textCode[0];
curCodeParm = textCode[1];
- if (isdigit(curCodeParm)) {
+ if (isdigit(static_cast<unsigned char>(curCodeParm))) {
curCodeParm -= '0';
} else {
curCodeParm = -1;
diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp
index 1256db8969..d047eb10a1 100644
--- a/engines/sci/graphics/transitions.cpp
+++ b/engines/sci/graphics/transitions.cpp
@@ -189,14 +189,6 @@ void GfxTransitions::doit(Common::Rect picRect) {
// Now we do the actual transition to the new screen
doTransition(_number, false);
- if (picRect.bottom != _screen->getHeight()) {
- // TODO: this is a workaround for lsl6 not showing menubar when playing
- // There is some new code in the sierra sci in ShowPic that seems to do
- // something similar to this
- _screen->copyToScreen();
- g_system->updateScreen();
- }
-
_screen->_picNotValid = 0;
}
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 5c8e9c3d2e..6ca4903e17 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -202,7 +202,7 @@ void GfxView::initData(GuiResourceId resourceId) {
palOffset = READ_SCI11ENDIAN_UINT32(_resourceData + 8);
// For SCI32, this is a scale flag
- if (getSciVersion() >= SCI_VERSION_2) {
+ if (getSciVersion() >= SCI_VERSION_2) {
_sci2ScaleRes = (Sci32ViewNativeResolution)_resourceData[5];
if (_screen->getUpscaledHires() == GFX_SCREEN_UPSCALED_DISABLED)
_sci2ScaleRes = SCI_VIEW_NATIVERES_NONE;
@@ -426,7 +426,7 @@ void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCo
// compression for SCI1.1+ Mac
while (pixelNr < pixelCount) {
uint32 pixelLine = pixelNr;
-
+
if (hasByteLengths) {
pixelNr += *rlePtr++;
runLength = *rlePtr++;
@@ -500,7 +500,7 @@ void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCo
} else {
memcpy(outPtr + pixelNr, literalPtr, MIN<uint16>(runLength, pixelCount - pixelNr));
literalPtr += runLength;
- }
+ }
break;
case 0x80: // fill with color
if (!literalPos)
@@ -692,7 +692,7 @@ void GfxView::draw(const Common::Rect &rect, const Common::Rect &clipRect, const
const int16 celHeight = celInfo->height;
const int16 celWidth = celInfo->width;
const byte clearKey = celInfo->clearKey;
- const byte drawMask = (priority == 255) ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
+ const byte drawMask = priority > 15 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
int x, y;
if (_embeddedPal)
@@ -753,7 +753,7 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect,
const int16 celHeight = celInfo->height;
const int16 celWidth = celInfo->width;
const byte clearKey = celInfo->clearKey;
- const byte drawMask = (priority == 255) ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
+ const byte drawMask = priority > 15 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
uint16 scalingX[640];
uint16 scalingY[480];
int16 scaledWidth, scaledHeight;
diff --git a/engines/sci/parser/said.cpp b/engines/sci/parser/said.cpp
index 827e28073a..01c25ef401 100644
--- a/engines/sci/parser/said.cpp
+++ b/engines/sci/parser/said.cpp
@@ -224,7 +224,7 @@ static bool parsePart2(ParseTreeNode* parentNode, bool& nonempty)
} else if (said_tokens[said_token] == TOKEN_BRACKETO) {
said_token++;
-
+
found = parsePart2(newNode, nonempty);
if (found) {
@@ -282,7 +282,7 @@ static bool parsePart3(ParseTreeNode* parentNode, bool& nonempty)
} else if (said_tokens[said_token] == TOKEN_BRACKETO) {
said_token++;
-
+
found = parsePart3(newNode, nonempty);
if (found) {
@@ -366,7 +366,7 @@ static bool parseRef(ParseTreeNode* parentNode)
said_attach_subtree(newParent, 0x144, 0x14f, newNode);
newParent = newParent->right;
-
+
newNode = said_branch_node(said_next_node(), 0, 0);
found = parseRef(newNode);
@@ -381,14 +381,14 @@ static bool parseRef(ParseTreeNode* parentNode)
}
- }
+ }
// NB: This is not an "else if'.
// If there is a "< [ ... ]", that is parsed as "< ..."
if (said_tokens[said_token] == TOKEN_BRACKETO) {
said_token++;
-
+
found = parseRef(newNode);
if (found) {
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 308bd92ef4..f18b6c91f5 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -128,7 +128,7 @@ static const char *s_resourceTypeSuffixes[] = {
"trn", "rbt", "vmd", "chk", "",
"etc", "duk", "clu", "tga", "zzz",
"", "", ""
-};
+};
const char *getResourceTypeName(ResourceType restype) {
if (restype != kResourceTypeInvalid)
@@ -449,11 +449,11 @@ bool MacResourceForkResourceSource::isCompressableResource(ResourceType type) co
*ptr++ = value; \
}
-void MacResourceForkResourceSource::decompressResource(Common::SeekableReadStream *stream, Resource *resource) const {
+void MacResourceForkResourceSource::decompressResource(Common::SeekableReadStream *stream, Resource *resource) const {
// KQ6 Mac is the only game not compressed. It's not worth writing a
// heuristic just for that game. Also, skip over any resource that cannot
// be compressed.
- bool canBeCompressed = !(g_sci && g_sci->getGameId() == GID_KQ6) && isCompressableResource(resource->_id.getType());
+ bool canBeCompressed = !(g_sci && g_sci->getGameId() == GID_KQ6) && isCompressableResource(resource->_id.getType());
uint32 uncompressedSize = 0;
// GK2 Mac is crazy. In its Patches resource fork, picture 2315 is not
@@ -503,7 +503,7 @@ void MacResourceForkResourceSource::decompressResource(Common::SeekableReadStrea
// Copy chunk expanded
extraByte1 = stream->readByte();
extraByte2 = stream->readByte();
-
+
literalLength = extraByte2 & 3;
OUTPUT_LITERAL()
@@ -824,7 +824,7 @@ void ChunkResourceSource::scanSource(ResourceManager *resMan) {
byte *ptr = chunk->data;
uint32 firstOffset = 0;
-
+
for (;;) {
ResourceType type = resMan->convertResType(*ptr);
uint16 number = READ_LE_UINT16(ptr + 1);
@@ -844,7 +844,7 @@ void ChunkResourceSource::scanSource(ResourceManager *resMan) {
// There's no end marker to the data table, but the first resource
// begins directly after the entry table. So, when we hit the first
// resource, we're at the end of the entry table.
-
+
if (!firstOffset)
firstOffset = entry.offset;
@@ -1243,7 +1243,7 @@ ResVersion ResourceManager::detectVolVersion() {
for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) {
rsrc = *it;
-
+
if (rsrc->getSourceType() == kSourceVolume) {
if (rsrc->_resourceFile) {
fileStream = rsrc->_resourceFile->createReadStream();
@@ -1291,7 +1291,7 @@ ResVersion ResourceManager::detectVolVersion() {
// loading SCI3 volumes, the format is otherwise
// identical to SCI2. We therefore get the compression
// indicator here, but disregard it in the following
- // code.
+ // code.
wCompression = fileStream->readUint16LE();
if (fileStream->eos()) {
@@ -1473,7 +1473,7 @@ void ResourceManager::readResourcePatchesBase36() {
name = (*x)->getName();
ResourceId resource36 = convertPatchNameBase36((ResourceType)i, name);
-
+
/*
if (i == kResourceTypeAudio36)
debug("audio36 patch: %s => %s. tuple:%d, %s\n", name.c_str(), inputName.c_str(), resource36.tuple, resource36.toString().c_str());
@@ -1494,7 +1494,7 @@ void ResourceManager::readResourcePatchesBase36() {
// Check for SOL as well
tag = (tag << 16) | stream->readUint16BE();
-
+
if (tag != MKTAG('S','O','L',0)) {
delete stream;
continue;
@@ -1555,7 +1555,7 @@ void ResourceManager::readResourcePatches() {
name = (*x)->getName();
// SCI1 scheme
- if (isdigit(name[0])) {
+ if (isdigit(static_cast<unsigned char>(name[0]))) {
char *end = 0;
resourceNr = strtol(name.c_str(), &end, 10);
bAdd = (*end == '.'); // Ensure the next character is the period
@@ -1563,7 +1563,7 @@ void ResourceManager::readResourcePatches() {
// SCI0 scheme
int resname_len = strlen(szResType);
if (scumm_strnicmp(name.c_str(), szResType, resname_len) == 0
- && !isalpha(name[resname_len + 1])) {
+ && !isalpha(static_cast<unsigned char>(name[resname_len + 1]))) {
resourceNr = atoi(name.c_str() + resname_len + 1);
bAdd = true;
}
@@ -1613,7 +1613,7 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) {
warning("Error while reading %s", map->getLocationName().c_str());
return SCI_ERROR_RESMAP_NOT_FOUND;
}
-
+
if (offset == 0xFFFFFFFF)
break;
@@ -2129,7 +2129,7 @@ void ResourceManager::detectSciVersion() {
bool oldDecompressors = true;
ResourceCompression viewCompression;
-#ifdef ENABLE_SCI32
+#ifdef ENABLE_SCI32
viewCompression = getViewCompression();
#else
if (_volVersion >= kResVersionSci2) {
@@ -2173,7 +2173,7 @@ void ResourceManager::detectSciVersion() {
}
#endif
}
-
+
if (_volVersion == kResVersionSci11Mac) {
// SCI32 doesn't have the resource.cfg file, so we can figure out
// which of the games are SCI1.1. Note that there are no Mac SCI2 games.
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 588ea76ea5..f3a3c8dd5b 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -197,7 +197,7 @@ void ResourceManager::readWaveAudioPatches() {
for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
Common::String name = (*x)->getName();
- if (isdigit(name[0]))
+ if (isdigit(static_cast<unsigned char>(name[0])))
processWavePatch(ResourceId(kResourceTypeAudio, atoi(name.c_str())), name);
}
}
@@ -356,14 +356,14 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
stream->seek(offset + 1);
byte headerSize = stream->readByte();
assert(headerSize == 11 || headerSize == 12);
-
+
stream->skip(5);
uint32 size = stream->readUint32LE() + headerSize + 2;
addResource(ResourceId(kResourceTypeAudio, n), src, offset, size);
}
} else {
- bool isEarly = (entrySize != 11);
+ bool isEarly = (entrySize != 11);
if (!isEarly) {
offset = READ_LE_UINT32(ptr);
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index cc9042ceb7..792b2b2055 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -282,7 +282,7 @@ Common::Error SciEngine::run() {
// without this games would be pretty badly broken
}
- // Show any special warnings for buggy scripts with severe game bugs,
+ // Show any special warnings for buggy scripts with severe game bugs,
// which have been patched by Sierra
if (getGameId() == GID_LONGBOW) {
// Longbow 1.0 has a buggy script which prevents the game
@@ -868,8 +868,9 @@ 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
+ if (getGameId() == GID_SQ4
|| getGameId() == GID_FREDDYPHARKAS
+ || getGameId() == GID_ECOQUEST
// TODO: The following need script patches for simultaneous speech and subtitles
//|| getGameId() == GID_KQ6
//|| getGameId() == GID_LAURABOW2
@@ -907,7 +908,7 @@ void SciEngine::loadMacExecutable() {
// KQ6/Freddy require the executable to load their icon bar palettes
if (hasMacIconBar())
error("Could not load Mac resource fork '%s'", filename.c_str());
-
+
// TODO: Show some sort of warning dialog saying they can't get any
// high-res Mac fonts, when we get to that point ;)
}
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 04ccbd97d2..b419d862a4 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -38,7 +38,7 @@ struct ADGameDescription;
* Status of this engine: ???
*
* Games using this engine:
- * - Newer Sierra adventure games (based on FreeSCI)
+ * - Newer Sierra adventure games (based on FreeSCI)
*
* @todo give a concrete list of supported games. Could also
* list future games, with status for each.
@@ -176,7 +176,7 @@ enum SciGameId {
GID_FANMADE // FIXME: Do we really need/want this?
};
-/**
+/**
* SCI versions
* For more information, check here:
* http://wiki.scummvm.org/index.php/Sierra_Game_Versions#SCI_Games
diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp
index 592caa5814..123dd21894 100644
--- a/engines/sci/sound/audio.cpp
+++ b/engines/sci/sound/audio.cpp
@@ -285,7 +285,7 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32
// instead.
memcpy(compressedData, audioRes->data, audioRes->size);
Common::SeekableReadStream *compressedStream = new Common::MemoryReadStream(compressedData, audioRes->size, DisposeAfterUse::YES);
-
+
switch (audioCompressionType) {
case MKTAG('M','P','3',' '):
#ifdef USE_MAD
diff --git a/engines/sci/sound/drivers/amigamac.cpp b/engines/sci/sound/drivers/amigamac.cpp
index 2f159c23ee..3c750401b9 100644
--- a/engines/sci/sound/drivers/amigamac.cpp
+++ b/engines/sci/sound/drivers/amigamac.cpp
@@ -24,6 +24,7 @@
#include "sci/sound/drivers/mididriver.h"
#include "sci/resource.h"
+#include "common/debug-channels.h"
#include "common/file.h"
#include "common/frac.h"
#include "common/memstream.h"
@@ -177,7 +178,7 @@ int MidiDriver_AmigaMac::interpolate(int8 *samples, frac_t offset, bool isUnsign
int diff = (s2 - s1) << 8;
return (s1 << 8) + fracToInt(diff * (offset & FRAC_LO_MASK));
}
-
+
int diff = (samples[x + 1] - samples[x]) << 8;
return (samples[x] << 8) + fracToInt(diff * (offset & FRAC_LO_MASK));
}
@@ -372,7 +373,7 @@ void MidiDriver_AmigaMac::setOutputFrac(int voice) {
fnote -= instrument->baseNote;
fnote *= 4;
// FIXME: check how SSCI maps this
- fnote += (_channels[_voices[voice].hw_channel].pitch - 0x2000) / 169;
+ fnote += (_channels[_voices[voice].hw_channel].pitch - 0x2000) / 169;
while (fnote < 0) {
divFact *= 2;
@@ -460,9 +461,9 @@ MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(C
instrument->fixedNote = 101;
instrument->mode = header[33];
- instrument->transpose = (int8) header[34];
+ instrument->transpose = (int8)header[34];
for (int i = 0; i < 4; i++) {
- int length = (int8) header[49 + i];
+ int length = (int8)header[49 + i];
if (length == 0 && i > 0)
length = 256;
@@ -482,13 +483,18 @@ MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(C
strncpy(instrument->name, (char *) header + 2, 29);
instrument->name[29] = 0;
- debugC(kDebugLevelSound, "Amiga/Mac driver: Reading instrument %i: \"%s\" (%i bytes)",
- *id, instrument->name, size);
- debugC(kDebugLevelSound, " Mode: %02x", instrument->mode);
- debugC(kDebugLevelSound, " Looping: %s", instrument->mode & kModeLoop ? "on" : "off");
- debugC(kDebugLevelSound, " Pitch changes: %s", instrument->mode & kModePitch ? "on" : "off");
- debugC(kDebugLevelSound, " Segment sizes: %i %i %i", seg_size[0], seg_size[1], seg_size[2]);
- debugC(kDebugLevelSound, " Segment offsets: 0 %i %i", loop_offset, (int32)READ_BE_UINT32(header + 43));
+ if (DebugMan.isDebugChannelEnabled(kDebugLevelSound)) {
+ debug("Amiga/Mac driver: Reading instrument %i: \"%s\" (%i bytes)",
+ *id, instrument->name, size);
+ debugN(" Mode: %02x (", header[33]);
+ debugN("looping: %s, ", header[33] & kModeLoop ? "on" : "off");
+ debug("pitch changes: %s)", header[33] & kModePitch ? "on" : "off");
+ debug(" Transpose: %i", (int8)header[34]);
+ for (uint i = 0; i < 3; i++)
+ debug(" Segment %i: %i words @ offset %i", i, (int16)READ_BE_UINT16(header + 35 + 6 * i), (i == 0 ? 0 : (int32)READ_BE_UINT32(header + 31 + 6 * i)));
+ for (uint i = 0; i < 4; i++)
+ debug(" Envelope %i: period %i / delta %i / target %i", i, header[49 + i], (int8)header[53 + i], header[57 + i]);
+ }
instrument->samples = (int8 *) malloc(size + 1);
if (file.read(instrument->samples, size) < (unsigned int)size) {
@@ -503,10 +509,8 @@ MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(C
if (instrument->mode & kModeLoop) {
if (loop_offset + seg_size[1] > size) {
-#ifdef DEBUG
- warning("Amiga/Mac driver: looping samples extend %i bytes past end of sample block",
- loop_offset + seg_size[1] - size);
-#endif
+ debugC(kDebugLevelSound, "Amiga/Mac driver: looping samples extend %i bytes past end of sample block",
+ loop_offset + seg_size[1] - size);
seg_size[1] = size - loop_offset;
}
@@ -613,7 +617,7 @@ int MidiDriver_AmigaMac::open() {
} else if (!loadInstrumentsSCI0Mac(stream))
return Common::kUnknownError;
}
-
+
MidiDriver_Emulated::open();
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
@@ -667,15 +671,11 @@ void MidiDriver_AmigaMac::send(uint32 b) {
break;
case 0x0a: // pan
// TODO
-#ifdef DEBUG
- warning("Amiga/Mac driver: ignoring pan 0x%02x event for channel %i", op2, channel);
-#endif
+ debugC(1, kDebugLevelSound, "Amiga/Mac driver: ignoring pan 0x%02x event for channel %i", op2, channel);
break;
case 0x40: // hold
// TODO
-#ifdef DEBUG
- warning("Amiga/Mac driver: ignoring hold 0x%02x event for channel %i", op2, channel);
-#endif
+ debugC(1, kDebugLevelSound, "Amiga/Mac driver: ignoring hold 0x%02x event for channel %i", op2, channel);
break;
case 0x4b: // voice mapping
break;
@@ -760,9 +760,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI0(Common::File &file) {
_bank.size = READ_BE_UINT16(header + 38);
strncpy(_bank.name, (char *) header + 8, 29);
_bank.name[29] = 0;
-#ifdef DEBUG
- debugN("Amiga/Mac driver: Reading %i instruments from bank \"%s\"\n", _bank.size, _bank.name);
-#endif
+ debugC(kDebugLevelSound, "Amiga/Mac driver: Reading %i instruments from bank \"%s\"", _bank.size, _bank.name);
for (uint i = 0; i < _bank.size; i++) {
int id;
@@ -799,9 +797,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI0Mac(Common::SeekableReadStream &fil
_bank.size = 128;
strncpy(_bank.name, (char *) header + 8, 29);
_bank.name[29] = 0;
-#ifdef DEBUG
- debugN("Amiga/Mac driver: Reading %i instruments from bank \"%s\"\n", _bank.size, _bank.name);
-#endif
+ debugC(kDebugLevelSound, "Amiga/Mac driver: Reading %i instruments from bank \"%s\"", _bank.size, _bank.name);
Common::Array<uint32> instrumentOffsets;
instrumentOffsets.resize(_bank.size);
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 96cbf135ed..2afab3858d 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -291,8 +291,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
if (_soundVersion >= SCI_VERSION_1_EARLY && g_sci->getPlatform() == Common::kPlatformAmiga)
flags = 0;
int endPart = track->digitalSampleEnd > 0 ? (track->digitalSampleSize - track->digitalSampleEnd) : 0;
- pSnd->pStreamAud = Audio::makeRawStream(channelData + track->digitalSampleStart,
- track->digitalSampleSize - track->digitalSampleStart - endPart,
+ pSnd->pStreamAud = Audio::makeRawStream(channelData + track->digitalSampleStart,
+ track->digitalSampleSize - track->digitalSampleStart - endPart,
track->digitalSampleRate, flags, DisposeAfterUse::NO);
delete pSnd->pLoopStream;
pSnd->pLoopStream = 0;
diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index d394fd0b2b..77f45e0788 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -53,14 +53,14 @@ namespace Sci {
// Taken from http://anthonylarme.tripod.com/phantas/phintgtp.html
//
// (...) What we needed was a way of playing video, but have it blend into
-// normal room art instead of occupying its own rectangular area. Room art
-// consists of a background pic overlaid with various animating cels
-// (traditional lingo: sprites). The cels each have a priority that determines
-// who is on top and who is behind in the drawing order. Cels are read from
-// *.v56 files (another proprietary format). A Robot is video frames with
-// transparent background including priority and x,y information. Thus, it is
+// normal room art instead of occupying its own rectangular area. Room art
+// consists of a background pic overlaid with various animating cels
+// (traditional lingo: sprites). The cels each have a priority that determines
+// who is on top and who is behind in the drawing order. Cels are read from
+// *.v56 files (another proprietary format). A Robot is video frames with
+// transparent background including priority and x,y information. Thus, it is
// like a cel, except it comes from an RBT - not a v56. Because it blends into
-// our graphics engine, it looks just like a part of the room. A RBT can move
+// our graphics engine, it looks just like a part of the room. A RBT can move
// around the screen and go behind other objects. (...)
#ifdef ENABLE_SCI32
@@ -105,7 +105,7 @@ bool RobotDecoder::loadStream(Common::SeekableReadStream *stream) {
_surface = new Graphics::Surface();
readHeaderChunk();
-
+
// There are several versions of robot files, ranging from 3 to 6.
// v3: no known examples
// v4: PQ:SWAT demo
@@ -223,7 +223,7 @@ void RobotDecoder::calculateVideoDimensions() {
// This is an O(n) operation, as each frame has a different size.
// We need to know the actual frame size to have a constant video size.
uint32 pos = _fileStream->pos();
-
+
for (uint32 curFrame = 0; curFrame < _header.frameCount; curFrame++) {
_fileStream->skip(4);
uint16 frameWidth = _fileStream->readUint16();
@@ -327,8 +327,8 @@ const Graphics::Surface *RobotDecoder::decodeNextFrame() {
// FIXME: For some reason, there are audio hiccups/gaps
if (_header.hasSound) {
_fileStream->skip(8); // header
- _audioStream->queueBuffer(g_sci->_audio->getDecodedRobotAudioFrame(_fileStream, audioChunkSize - 8),
- (audioChunkSize - 8) * 2, DisposeAfterUse::NO,
+ _audioStream->queueBuffer(g_sci->_audio->getDecodedRobotAudioFrame(_fileStream, audioChunkSize - 8),
+ (audioChunkSize - 8) * 2, DisposeAfterUse::NO,
Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN);
} else {
_fileStream->skip(audioChunkSize);
@@ -359,7 +359,7 @@ void RobotDecoder::close() {
}
reset();
-}
+}
#endif
diff --git a/engines/sci/video/seq_decoder.h b/engines/sci/video/seq_decoder.h
index f5e8ad9b05..800a3c9024 100644
--- a/engines/sci/video/seq_decoder.h
+++ b/engines/sci/video/seq_decoder.h
@@ -58,7 +58,7 @@ public:
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
const byte *getPalette() { _dirtyPalette = false; return _palette; }
bool hasDirtyPalette() const { return _dirtyPalette; }
-
+
protected:
Common::Rational getFrameRate() const { assert(_frameDelay); return Common::Rational(60, _frameDelay); }
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index e4057d1f13..20b929dfd4 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1066,7 +1066,7 @@ static int checkXYInBoxBounds(int boxnum, int x, int y, int &destX, int &destY)
int dist;
// MM C64: This fixes the trunk bug (#3070065), as well
- // as the fruit bowl, however im not sure if its
+ // as the fruit bowl, however im not sure if its
// the proper solution or not.
if( g_scumm->_game.version == 0 )
yDist = ABS(y - destY);
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index dce6c9c144..7fb834ce98 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -50,6 +50,7 @@ void ScummEngine::loadCJKFont() {
if (_game.version <= 5 && _game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN) { // FM-TOWNS v3 / v5 Kanji
#ifdef DISABLE_TOWNS_DUAL_LAYER_MODE
+ GUIErrorMessage("FM-Towns Kanji font drawing requires dual graphics layer support which is disabled in this build");
error("FM-Towns Kanji font drawing requires dual graphics layer support which is disabled in this build");
#else
// use FM-TOWNS font rom, since game files don't have kanji font resources
@@ -788,8 +789,10 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
else if (_vm->_cjkFont)
_vm->_cjkFont->drawChar(_vm->_textSurface, chr, _left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier, _color, _shadowColor);
#endif
- if (is2byte)
+ if (is2byte) {
origWidth /= _vm->_textSurfaceMultiplier;
+ height /= _vm->_textSurfaceMultiplier;
+ }
}
if (_str.left > _left)
@@ -803,8 +806,8 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
_str.right++;
}
- if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
- _str.bottom = _top + height / _vm->_textSurfaceMultiplier;
+ if (_str.bottom < _top + height)
+ _str.bottom = _top + height;
}
void CharsetRendererV3::drawChar(int chr, Graphics::Surface &s, int x, int y) {
@@ -1067,7 +1070,7 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
Graphics::Surface backSurface;
if ((ignoreCharsetMask || !vs->hasTwoBuffers)
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
- && (_vm->_game.platform != Common::kPlatformFMTowns)
+ && (_vm->_game.platform != Common::kPlatformFMTowns)
#endif
) {
dstSurface = *vs;
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp
index 75cde5e33a..4ca4988605 100644
--- a/engines/scumm/costume.cpp
+++ b/engines/scumm/costume.cpp
@@ -73,10 +73,10 @@ static const int v1MMNESLookup[25] = {
};
static const byte v0ActorTalkArray[0x19] = {
- 0x00, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x00, 0x46, 0x06,
- 0x06, 0x06, 0x06, 0xFF, 0xFF,
- 0x06, 0xC0, 0x06, 0x06, 0x00,
+ 0x00, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x00, 0x46, 0x06,
+ 0x06, 0x06, 0x06, 0xFF, 0xFF,
+ 0x06, 0xC0, 0x06, 0x06, 0x00,
0xC0, 0xC0, 0x00, 0x06, 0x06
};
@@ -1417,7 +1417,7 @@ byte C64CostumeLoader::increaseAnims(Actor *a) {
if (A->_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) {
if (a->_cost.soundPos == 0)
a->_cost.soundCounter++;
-
+
// Is this the correct location?
// 0x073C
if (v0ActorTalkArray[a->_number] & 0x3F)
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index e9b5260eca..a8adb4d5c5 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -551,7 +551,7 @@ void ScummEngine_v5::setBuiltinCursor(int idx) {
uint16 color;
const uint16 *src = _cursorImages[_currentCursor];
- if (_bytesPerPixelOutput == 2) {
+ if (_outputPixelFormat.bytesPerPixel == 2) {
if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) {
byte r, g, b;
colorPCEToRGB(default_pce_cursor_colors[idx], &r, &g, &b);
@@ -577,14 +577,14 @@ void ScummEngine_v5::setBuiltinCursor(int idx) {
_cursor.width = 16 * _textSurfaceMultiplier;
_cursor.height = 16 * _textSurfaceMultiplier;
- int scl = _bytesPerPixelOutput * _textSurfaceMultiplier;
+ int scl = _outputPixelFormat.bytesPerPixel * _textSurfaceMultiplier;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
if (src[i] & (1 << j)) {
byte *dst1 = _grabbedCursor + 16 * scl * i * _textSurfaceMultiplier + (15 - j) * scl;
byte *dst2 = (_textSurfaceMultiplier == 2) ? dst1 + 16 * scl : dst1;
- if (_bytesPerPixelOutput == 2) {
+ if (_outputPixelFormat.bytesPerPixel == 2) {
for (int b = 0; b < scl; b += 2) {
*((uint16*)dst1) = *((uint16*)dst2) = color;
dst1 += 2;
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index aecd13db5a..18f2f4ddec 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -272,7 +272,7 @@ static BaseScummFile *openDiskImage(const Common::FSNode &node, const GameFilena
GameSettings gs;
memset(&gs, 0, sizeof(GameSettings));
gs.gameid = gfp->gameid;
- gs.id = (Common::String(gfp->gameid) == "maniac" ? GID_MANIAC : GID_ZAK);
+ gs.id = (Common::String(gfp->gameid) == "maniac" ? GID_MANIAC : GID_ZAK);
gs.platform = gfp->platform;
// determine second disk file name
@@ -431,7 +431,7 @@ static void computeGameSettingsFromMD5(const Common::FSList &fslist, const GameF
}
}
-static void composeFileHashMap(const Common::FSList &fslist, DescMap &fileMD5Map, int depth, const char **globs) {
+static void composeFileHashMap(DescMap &fileMD5Map, const Common::FSList &fslist, int depth, const char **globs) {
if (depth <= 0)
return;
@@ -454,14 +454,13 @@ static void composeFileHashMap(const Common::FSList &fslist, DescMap &fileMD5Map
matched = true;
break;
}
-
+
if (!matched)
continue;
Common::FSList files;
-
if (file->getChildren(files, Common::FSNode::kListAll)) {
- composeFileHashMap(files, fileMD5Map, depth - 1, globs);
+ composeFileHashMap(fileMD5Map, files, depth - 1, globs);
}
}
}
@@ -472,7 +471,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
DetectorResult dr;
// Dive one level down since mac indy3/loom has its files split into directories. See Bug #1438631
- composeFileHashMap(fslist, fileMD5Map, 2, directoryGlobs);
+ composeFileHashMap(fileMD5Map, fslist, 2, directoryGlobs);
// Iterate over all filename patterns.
for (const GameFilenamePattern *gfp = gameFilenamesTable; gfp->gameid; ++gfp) {
@@ -516,7 +515,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
if (d.md5.empty()) {
Common::SeekableReadStream *tmp = 0;
bool isDiskImg = (file.hasSuffix(".d64") || file.hasSuffix(".dsk") || file.hasSuffix(".prg"));
-
+
if (isDiskImg) {
tmp = openDiskImage(d.node, gfp);
@@ -882,7 +881,7 @@ GameList ScummMetaEngine::getSupportedGames() const {
}
GameDescriptor ScummMetaEngine::findGame(const char *gameid) const {
- return AdvancedDetector::findGameID(gameid, gameDescriptions, obsoleteGameIDsTable);
+ return Engines::findGameID(gameid, gameDescriptions, obsoleteGameIDsTable);
}
static Common::String generatePreferredTarget(const DetectorResult &x) {
@@ -975,20 +974,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co
// We start by checking whether the specified game ID is obsolete.
// If that is the case, we automatically upgrade the target to use
// the correct new game ID (and platform, if specified).
- for (const ADObsoleteGameID *o = obsoleteGameIDsTable; o->from; ++o) {
- if (!scumm_stricmp(gameid, o->from)) {
- // Match found, perform upgrade
- gameid = o->to;
- ConfMan.set("gameid", o->to);
-
- if (o->platform != Common::kPlatformUnknown)
- ConfMan.set("platform", Common::getPlatformCode(o->platform));
-
- warning("Target upgraded from game ID %s to %s", o->from, o->to);
- ConfMan.flushToDisk();
- break;
- }
- }
+ Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable);
// Fetch the list of files in the current directory
Common::FSList fslist;
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 7eb1e80132..e510c46cf2 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -23,7 +23,7 @@
#ifndef SCUMM_DETECTION_TABLES_H
#define SCUMM_DETECTION_TABLES_H
-#include "engines/advancedDetector.h"
+#include "engines/obsolete.h"
#include "common/rect.h"
#include "common/util.h"
@@ -145,7 +145,7 @@ static const PlainGameDescriptor gameDescriptions[] = {
* Conversion table mapping old obsolete game IDs to the
* corresponding new game ID and platform combination.
*/
-static const ADObsoleteGameID obsoleteGameIDsTable[] = {
+static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = {
{"bluesabctimedemo", "bluesabctime", UNK},
{"BluesBirthdayDemo", "BluesBirthday", UNK},
{"comidemo", "comi", UNK},
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 1b913e16b4..f22547f193 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -251,7 +251,7 @@ GdiV2::~GdiV2() {
}
#ifdef USE_RGB_COLOR
-Gdi16Bit::Gdi16Bit(ScummEngine *vm) : Gdi(vm) {
+GdiHE16bit::GdiHE16bit(ScummEngine *vm) : GdiHE(vm) {
}
#endif
@@ -652,16 +652,13 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
assert(0 == (width & 3));
// Compose the text over the game graphics
-#ifdef USE_ARM_GFX_ASM
- asmDrawStripToScreen(height, width, text, src, _compositeBuf, vs->pitch, width, _textSurface.pitch);
-#else
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_game.platform == Common::kPlatformFMTowns) {
towns_drawStripToScreen(vs, x, y, x, top, width, height);
- return;
+ return;
} else
-#endif
- if (_bytesPerPixelOutput == 2) {
+#endif
+ if (_outputPixelFormat.bytesPerPixel == 2) {
const byte *srcPtr = (const byte *)src;
const byte *textPtr = (byte *)_textSurface.getBasePtr(x * m, y * m);
byte *dstPtr = _compositeBuf;
@@ -682,7 +679,11 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
srcPtr += vsPitch;
textPtr += _textSurface.pitch - width * m;
}
- } else {
+ }
+#ifdef USE_ARM_GFX_ASM
+ asmDrawStripToScreen(height, width, text, src, _compositeBuf, vs->pitch, width, _textSurface.pitch);
+#else
+ else {
// We blit four pixels at a time, for improved performance.
const uint32 *src32 = (const uint32 *)src;
uint32 *dst32 = (uint32 *)_compositeBuf;
@@ -721,11 +722,11 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height);
- src = _herculesBuf + x + y * Common::kHercW;
- pitch = Common::kHercW;
+ src = _herculesBuf + x + y * kHercWidth;
+ pitch = kHercWidth;
// center image on the screen
- x += (Common::kHercW - _screenWidth * 2) / 2; // (720 - 320*2)/2 = 40
+ x += (kHercWidth - _screenWidth * 2) / 2; // (720 - 320*2)/2 = 40
} else if (_useCJKMode && m == 2) {
pitch *= m;
x *= m;
@@ -818,10 +819,10 @@ void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *wid
int dsty = yo*2 - yo/4;
for (int y1 = 0; y1 < heighto;) {
- assert(dsty < Common::kHercH);
+ assert(dsty < kHercHeight);
srcptr = src + y1 * srcPitch;
- dstptr = hercbuf + dsty * Common::kHercW + xo * 2;
+ dstptr = hercbuf + dsty * kHercWidth + xo * 2;
const int idx1 = (dsty % 7) % 2;
for (int x1 = 0; x1 < widtho; x1++) {
@@ -1023,7 +1024,7 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) {
if (rect.left > vs->w)
return;
-
+
// Convert 'rect' to local (virtual screen) coordinates
rect.top -= vs->topline;
rect.bottom -= vs->topline;
@@ -1067,7 +1068,7 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) {
fill(mask, _textSurface.pitch, backColor, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel);
}
#endif
-
+
if (_game.features & GF_16BIT_COLOR)
fill(screenBuf, vs->pitch, _16BitPalette[backColor], width, height, vs->format.bytesPerPixel);
else
@@ -1127,7 +1128,7 @@ void ScummEngine::clearTextSurface() {
fill((byte*)_textSurface.pixels, _textSurface.pitch,
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
_game.platform == Common::kPlatformFMTowns ? 0 :
-#endif
+#endif
CHARSET_MASK_TRANSPARENCY, _textSurface.w, _textSurface.h, _textSurface.format.bytesPerPixel);
}
@@ -1344,12 +1345,12 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) {
color = ((color & 0x0f) << 4) | (color & 0x0f);
byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop + vs->topline) * _textSurfaceMultiplier);
fill(mask, _textSurface.pitch, color, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel);
-
+
if (_game.id == GID_MONKEY2 || _game.id == GID_INDY4 || ((_game.id == GID_INDY3 || _game.id == GID_ZAK) && vs->number != kTextVirtScreen) || (_game.id == GID_LOOM && vs->number == kMainVirtScreen))
return;
}
#endif
-
+
fill(backbuff, vs->pitch, color, width, height, vs->format.bytesPerPixel);
}
}
@@ -3673,7 +3674,7 @@ void Gdi::unkDecode11(byte *dst, int dstPitch, const byte *src, int height) cons
#undef READ_BIT_256
#ifdef USE_RGB_COLOR
-void Gdi16Bit::writeRoomColor(byte *dst, byte color) const {
+void GdiHE16bit::writeRoomColor(byte *dst, byte color) const {
WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
}
#endif
@@ -4009,7 +4010,7 @@ void ScummEngine::scrollEffect(int dir) {
y = 1 + step;
while (y < vs->h) {
moveScreen(0, -step, vs->h);
-#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
+#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_townsScreen) {
towns_drawStripToScreen(vs, 0, vs->topline + vs->h - step, 0, y - step, vs->w, step);
} else
@@ -4022,7 +4023,7 @@ void ScummEngine::scrollEffect(int dir) {
vs->w * m, step * m);
_system->updateScreen();
}
-
+
waitForTimer(delay);
y += step;
}
@@ -4045,7 +4046,7 @@ void ScummEngine::scrollEffect(int dir) {
vs->w * m, step * m);
_system->updateScreen();
}
-
+
waitForTimer(delay);
y += step;
}
@@ -4092,7 +4093,7 @@ void ScummEngine::scrollEffect(int dir) {
0, 0,
step, vs->h);
_system->updateScreen();
- }
+ }
waitForTimer(delay);
x += step;
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index 6da07efd18..4b44ddc376 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -32,6 +32,11 @@ namespace Scumm {
class ScummEngine;
+enum HerculesDimensions {
+ kHercWidth = 720,
+ kHercHeight = 350
+};
+
/** Camera modes */
enum {
kNormalCameraMode = 1,
@@ -430,11 +435,11 @@ public:
};
#ifdef USE_RGB_COLOR
-class Gdi16Bit : public Gdi {
+class GdiHE16bit : public GdiHE {
protected:
virtual void writeRoomColor(byte *dst, byte color) const;
public:
- Gdi16Bit(ScummEngine *vm);
+ GdiHE16bit(ScummEngine *vm);
};
#endif
@@ -443,21 +448,21 @@ public:
// switching graphics layers on and off).
class TownsScreen {
public:
- TownsScreen(OSystem *system, int width, int height, int bpp);
+ TownsScreen(OSystem *system, int width, int height, Graphics::PixelFormat &format);
~TownsScreen();
void setupLayer(int layer, int width, int height, int numCol, void *srcPal = 0);
void clearLayer(int layer);
void fillLayerRect(int layer, int x, int y, int w, int h, int col);
//void copyRectToLayer(int layer, int x, int y, int w, int h, const uint8 *src);
-
+
uint8 *getLayerPixels(int layer, int x, int y);
int getLayerPitch(int layer);
int getLayerHeight(int layer);
int getLayerBpp(int layer);
int getLayerScaleW(int layer);
int getLayerScaleH(int layer);
-
+
void addDirtyRect(int x, int y, int w, int h);
void toggleLayers(int flag);
void update();
@@ -484,16 +489,16 @@ private:
uint8 **bltInternY;
uint16 *bltTmpPal;
} _layers[2];
-
+
uint8 *_outBuffer;
int _height;
int _width;
int _pitch;
- int _bpp;
-
+ Graphics::PixelFormat _pixelFormat;
+
int _numDirtyRects;
- Common::List<Common::Rect> _dirtyRects;
+ Common::List<Common::Rect> _dirtyRects;
OSystem *_system;
};
#endif // DISABLE_TOWNS_DUAL_LAYER_MODE
diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp
index 82bb32cdfb..6a3f50a1af 100644
--- a/engines/scumm/gfx_towns.cpp
+++ b/engines/scumm/gfx_towns.cpp
@@ -47,13 +47,13 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
int dp2 = _townsScreen->getLayerPitch(1) - width * m * _townsScreen->getLayerBpp(1);
int sp1 = vs->pitch - (width * vs->format.bytesPerPixel);
int sp2 = _textSurface.pitch - width * m;
-
+
if (vs->number == kMainVirtScreen || _game.id == GID_INDY3 || _game.id == GID_ZAK) {
for (int h = 0; h < height; ++h) {
- if (_bytesPerPixelOutput == 2) {
+ if (_outputPixelFormat.bytesPerPixel == 2) {
for (int w = 0; w < width; ++w) {
*(uint16*)dst1 = _16BitPalette[*src1++];
- dst1 += _bytesPerPixelOutput;
+ dst1 += _outputPixelFormat.bytesPerPixel;
}
src1 += sp1;
@@ -63,13 +63,13 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
src1 += vs->pitch;
dst1 += _townsScreen->getLayerPitch(0);
}
-
+
for (int sH = 0; sH < m; ++sH) {
memcpy(dst2, src2, width * m);
src2 += _textSurface.pitch;
dst2 += _townsScreen->getLayerPitch(1);
}
- }
+ }
} else {
dst1 = dst2;
for (int h = 0; h < height; ++h) {
@@ -81,7 +81,7 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
dst1 = dst2;
uint8 *src3 = src2;
-
+
if (m == 2) {
dst2 += _townsScreen->getLayerPitch(1);
src3 += _townsScreen->getLayerPitch(1);
@@ -95,7 +95,7 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
dst1++;
}
- src1 += sp1;
+ src1 += sp1;
src2 = src3 + sp2;
dst1 = dst2 + dp2;
dst2 += dp2;
@@ -197,8 +197,8 @@ const uint8 ScummEngine::_townsLayer2Mask[] = {
#define DIRTY_RECTS_MAX 20
#define FULL_REDRAW (DIRTY_RECTS_MAX + 1)
-TownsScreen::TownsScreen(OSystem *system, int width, int height, int bpp) :
- _system(system), _width(width), _height(height), _bpp(bpp), _pitch(width * bpp) {
+TownsScreen::TownsScreen(OSystem *system, int width, int height, Graphics::PixelFormat &format) :
+ _system(system), _width(width), _height(height), _pixelFormat(format), _pitch(width * format.bytesPerPixel) {
memset(&_layers[0], 0, sizeof(TownsScreenLayer));
memset(&_layers[1], 0, sizeof(TownsScreenLayer));
_outBuffer = new byte[_pitch * _height];
@@ -231,7 +231,7 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
if (width > _width || height > _height)
error("TownsScreen::setupLayer(): Layer width/height must be equal or less than screen width/height");
-
+
l->scaleW = _width / width;
l->scaleH = _height / height;
@@ -247,8 +247,8 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
l->pitch = width * l->bpp;
l->palette = (uint8*)pal;
- if (l->palette && _bpp == 1)
- warning("TownsScreen::setupLayer(): Layer palette usage requires 15 bit graphics setting.\nLayer palette will be ignored.");
+ if (l->palette && _pixelFormat.bytesPerPixel == 1)
+ warning("TownsScreen::setupLayer(): Layer palette usage requires 16 bit graphics setting.\nLayer palette will be ignored.");
delete[] l->pixels;
l->pixels = new uint8[l->pitch * l->height];
@@ -267,13 +267,14 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
l->bltInternY[i] = l->pixels + (i / l->scaleH) * l->pitch;
delete[] l->bltTmpPal;
- l->bltTmpPal = (l->bpp == 1 && _bpp == 2) ? new uint16[l->numCol] : 0;
-
+ l->bltTmpPal = (l->bpp == 1 && _pixelFormat.bytesPerPixel == 2) ? new uint16[l->numCol] : 0;
+
l->enabled = true;
- l->onBottom = (!layer || !_layers[0].enabled);
+ _layers[0].onBottom = true;
+ _layers[1].onBottom = _layers[0].enabled ? false : true;
l->ready = true;
}
-
+
void TownsScreen::clearLayer(int layer) {
if (layer < 0 || layer > 1)
return;
@@ -299,10 +300,10 @@ void TownsScreen::fillLayerRect(int layer, int x, int y, int w, int h, int col)
assert(x >= 0 && y >= 0 && ((x + w) * l->bpp) <= (l->pitch) && (y + h) <= (l->height));
uint8 *pos = l->pixels + y * l->pitch + x * l->bpp;
-
+
for (int i = 0; i < h; ++i) {
if (l->bpp == 2) {
- for (int ii = 0; ii < w; ++ii) {
+ for (int ii = 0; ii < w; ++ii) {
*(uint16*)pos = col;
pos += 2;
}
@@ -358,8 +359,8 @@ int TownsScreen::getLayerScaleH(int layer) {
void TownsScreen::addDirtyRect(int x, int y, int w, int h) {
if (w <= 0 || h <= 0 || _numDirtyRects > DIRTY_RECTS_MAX)
- return;
-
+ return;
+
if (_numDirtyRects == DIRTY_RECTS_MAX) {
// full redraw
_dirtyRects.clear();
@@ -382,25 +383,25 @@ void TownsScreen::addDirtyRect(int x, int y, int w, int h) {
y = r->top;
skip = true;
}
-
+
if (x2 > r->left && x2 < r->right && y > r->top && y < r->bottom) {
x2 = r->right;
y = r->top;
skip = true;
}
-
+
if (x2 > r->left && x2 < r->right && y2 > r->top && y2 < r->bottom) {
x2 = r->right;
y2 = r->bottom;
skip = true;
}
-
+
if (x > r->left && x < r->right && y2 > r->top && y2 < r->bottom) {
x = r->left;
y2 = r->bottom;
skip = true;
- }
-
+ }
+
if (skip) {
r->left = x;
r->top = y;
@@ -420,10 +421,10 @@ void TownsScreen::toggleLayers(int flag) {
if (flag < 0 || flag > 3)
return;
- for (int i = 0; i < 2; ++i) {
- _layers[i].enabled = (flag & (i + 1)) ? true : false;
- _layers[i].onBottom = (!i || !_layers[0].enabled);
- }
+ _layers[0].enabled = (flag & 1) ? true : false;
+ _layers[0].onBottom = true;
+ _layers[1].enabled = (flag & 2) ? true : false;
+ _layers[1].onBottom = _layers[0].enabled ? false : true;
_dirtyRects.clear();
_dirtyRects.push_back(Common::Rect(_width - 1, _height - 1));
@@ -448,22 +449,24 @@ void TownsScreen::updateOutputBuffer() {
if (!l->enabled || !l->ready)
continue;
- uint8 *dst = _outBuffer + r->top * _pitch + r->left * _bpp;
- int ptch = _pitch - (r->right - r->left + 1) * _bpp;
+ uint8 *dst = _outBuffer + r->top * _pitch + r->left * _pixelFormat.bytesPerPixel;
+ int ptch = _pitch - (r->right - r->left + 1) * _pixelFormat.bytesPerPixel;
- if (_bpp == 2 && l->bpp == 1) {
+ if (_pixelFormat.bytesPerPixel == 2 && l->bpp == 1) {
+ if (!l->palette)
+ error("void TownsScreen::updateOutputBuffer(): No palette assigned to 8 bit layer %d", i);
for (int ic = 0; ic < l->numCol; ic++)
l->bltTmpPal[ic] = calc16BitColor(&l->palette[ic * 3]);
}
for (int y = r->top; y <= r->bottom; ++y) {
- if (l->bpp == _bpp && l->scaleW == 1 && l->onBottom) {
- memcpy(dst, l->bltInternY[y] + l->bltInternX[r->left], (r->right + 1 - r->left) * _bpp);
+ if (l->bpp == _pixelFormat.bytesPerPixel && l->scaleW == 1 && l->onBottom && l->numCol & 0xff00) {
+ memcpy(dst, &l->bltInternY[y][l->bltInternX[r->left]], (r->right + 1 - r->left) * _pixelFormat.bytesPerPixel);
dst += _pitch;
- } else if (_bpp == 2) {
+ } else if (_pixelFormat.bytesPerPixel == 2) {
for (int x = r->left; x <= r->right; ++x) {
- uint8 *src = l->bltInternY[y] + l->bltInternX[x];
+ uint8 *src = &l->bltInternY[y][l->bltInternX[x]];
if (l->bpp == 1) {
uint8 col = *src;
if (col || l->onBottom) {
@@ -480,16 +483,16 @@ void TownsScreen::updateOutputBuffer() {
} else {
for (int x = r->left; x <= r->right; ++x) {
- uint8 col = *(l->bltInternY[y] + l->bltInternX[x]);
+ uint8 col = l->bltInternY[y][l->bltInternX[x]];
if (col || l->onBottom) {
if (l->numCol == 16)
- col = (col >> 4) & (col & 0x0f);
+ col = (col >> 4) & (col & 0x0f);
*dst = col;
}
dst++;
}
dst += ptch;
- }
+ }
}
}
}
@@ -497,17 +500,13 @@ void TownsScreen::updateOutputBuffer() {
void TownsScreen::outputToScreen() {
for (Common::List<Common::Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i)
- _system->copyRectToScreen(_outBuffer + i->top * _pitch + i->left * _bpp, _pitch, i->left, i->top, i->right - i->left + 1, i->bottom - i->top + 1);
+ _system->copyRectToScreen(_outBuffer + i->top * _pitch + i->left * _pixelFormat.bytesPerPixel, _pitch, i->left, i->top, i->right - i->left + 1, i->bottom - i->top + 1);
_dirtyRects.clear();
_numDirtyRects = 0;
}
uint16 TownsScreen::calc16BitColor(const uint8 *palEntry) {
- uint16 ar = (palEntry[0] & 0xf8) << 7;
- uint16 ag = (palEntry[1] & 0xf8) << 2;
- uint16 ab = (palEntry[2] >> 3);
- uint16 col = ar | ag | ab;
- return col;
+ return _pixelFormat.RGBToColor(palEntry[0], palEntry[1], palEntry[2]);
}
#undef DIRTY_RECTS_MAX
diff --git a/engines/scumm/he/logic_he.cpp b/engines/scumm/he/logic_he.cpp
index a7d808e316..af56bca2ee 100644
--- a/engines/scumm/he/logic_he.cpp
+++ b/engines/scumm/he/logic_he.cpp
@@ -1018,7 +1018,7 @@ int LogicHEsoccer::op_1007(int32 *args) {
// Returns the square root of the sum of the squares of the arguments
static inline double sqrtSquare(double a1, double a2, double a3) {
return sqrt(a1 * a1 + a2 * a2 + a3 * a3);
-}
+}
int LogicHEsoccer::op_1008(int32 *args) {
// TODO: Used during a match (kicking?)
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp
index 4565bb9f26..39240e347f 100644
--- a/engines/scumm/he/resource_he.cpp
+++ b/engines/scumm/he/resource_he.cpp
@@ -166,7 +166,7 @@ bool MacResExtractor::extractResource(int id, CachedCursor *cc) {
}
Common::SeekableReadStream *dataStream = _resMgr->getResource('crsr', id + 1000);
-
+
if (!dataStream)
return false;
diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h
index 9978869ffc..6996ce81eb 100644
--- a/engines/scumm/he/resource_he.h
+++ b/engines/scumm/he/resource_he.h
@@ -61,7 +61,7 @@ private:
ResExtractor::CachedCursor *findCachedCursor(int id);
ResExtractor::CachedCursor *getCachedCursorSlot();
-
+
CachedCursor _cursorCache[MAX_CACHED_CURSORS];
};
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index fb070b3e27..cf7d9fbd2f 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -744,7 +744,7 @@ void ScummEngine_v60he::o60_closeFile() {
_hOutFileTable[slot] = 0;
}
- delete _hInFileTable[slot];
+ delete _hInFileTable[slot];
_hInFileTable[slot] = 0;
}
}
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 8f16bf0f3a..5af4035930 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -1446,7 +1446,7 @@ void ScummEngine_v72he::o72_openFile() {
_hOutFileTable[slot]->write(initialData, initialSize);
delete[] initialData;
}
-
+
} break;
default:
error("o72_openFile(): wrong open file mode %d", mode);
diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp
index 7d971f5ca4..317ef36cb9 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -26,6 +26,7 @@
#include "common/util.h"
#include "common/system.h"
+#include "common/endian.h"
#include "scumm/imuse/imuse.h"
#include "scumm/imuse/imuse_internal.h"
@@ -99,9 +100,15 @@ IMuseInternal::~IMuseInternal() {
}
}
-byte *IMuseInternal::findStartOfSound(int sound, int ct) {
+byte *IMuseInternal::findStartOfSound(int sound, int ct) {
int32 size, pos;
- static uint32 id[] = { 'MThd', 'FORM', 'MDhd', 'MDpg' };
+
+ static const uint32 id[] = {
+ MKTAG('M', 'T', 'h', 'd'),
+ MKTAG('F', 'O', 'R', 'M'),
+ MKTAG('M', 'D', 'h', 'd'),
+ MKTAG('M', 'D', 'p', 'g')
+ };
byte *ptr = g_scumm->_res->_types[rtSound][sound]._address;
@@ -945,7 +952,7 @@ void IMuseInternal::handle_marker(uint id, byte data) {
_trigger_count--;
_queue_cleared = false;
_queue_end = (_queue_end + 1) % ARRAYSIZE(_cmd_queue);
-
+
while (_queue_end != _queue_pos && _cmd_queue[_queue_end].array[0] == COMMAND_ID && !_queue_cleared) {
p = _cmd_queue[_queue_end].array;
doCommand_internal(p[1], p[2], p[3], p[4], p[5], p[6], p[7], 0);
diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h
index 8808a3655a..6a7b9fc7d9 100644
--- a/engines/scumm/imuse/imuse_internal.h
+++ b/engines/scumm/imuse/imuse_internal.h
@@ -450,7 +450,7 @@ protected:
kMThd = 1,
kFORM = 2,
kMDhd = 4, // Used in MI2 and INDY4. Contain certain start parameters (priority, volume, etc. ) for the player.
- kMDpg = 8 // These chunks exist in DOTT and SAMNMAX. They don't get processed, however.
+ kMDpg = 8 // These chunks exist in DOTT and SAMNMAX. They don't get processed, however.
};
byte *findStartOfSound(int sound, int ct = (kMThd | kFORM));
diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp
index 0b084f3116..61b9cad2cb 100644
--- a/engines/scumm/imuse/imuse_player.cpp
+++ b/engines/scumm/imuse/imuse_player.cpp
@@ -120,7 +120,7 @@ bool Player::startSound(int sound, MidiDriver *midi) {
_midi = NULL;
return false;
}
-
+
debugC(DEBUG_IMUSE, "Starting music %d", sound);
return true;
}
@@ -194,7 +194,7 @@ int Player::start_seq_sound(int sound, bool reset_vars) {
_parser->property(MidiParser::mpSmartJump, 1);
_parser->loadMusic(ptr, 0);
_parser->setTrack(_track_index);
-
+
ptr = _se->findStartOfSound(sound, IMuseInternal::kMDhd);
setSpeed(reset_vars ? (ptr ? (READ_BE_UINT32(&ptr[4]) && ptr[15] ? ptr[15] : 128) : 128) : _speed);
@@ -226,7 +226,7 @@ void Player::loadStartParameters(int sound) {
_pan = ptr[4];
_transpose = ptr[5];
_detune = ptr[6];
- setSpeed(ptr[7]);
+ setSpeed(ptr[7]);
}
}
}
diff --git a/engines/scumm/imuse/sysex_scumm.cpp b/engines/scumm/imuse/sysex_scumm.cpp
index 4eb3bee93c..c3bec93a60 100644
--- a/engines/scumm/imuse/sysex_scumm.cpp
+++ b/engines/scumm/imuse/sysex_scumm.cpp
@@ -76,7 +76,7 @@ void sysexHandler_Scumm(Player *player, const byte *msg, uint16 len) {
part->set_pri(p[4]);
part->volume((p[5] & 0x0F) << 4 |(p[6] & 0x0F));
part->set_pan((p[7] & 0x0F) << 4 | (p[8] & 0x0F));
- part->_percussion = player->_isMIDI ? ((p[9] & 0x08) > 0) : false;
+ part->_percussion = player->_isMIDI ? ((p[9] & 0x08) > 0) : false;
part->set_transpose((p[9] & 0x0F) << 4 | (p[10] & 0x0F));
part->set_detune((p[11] & 0x0F) << 4 | (p[12] & 0x0F));
part->pitchBendFactor((p[13] & 0x0F) << 4 | (p[14] & 0x0F));
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 07c52578c3..5eea7acc6b 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -181,7 +181,7 @@ void ScummEngine::parseEvent(Common::Event event) {
_mouse.y = event.mouse.y;
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- _mouse.x -= (Common::kHercW - _screenWidth * 2) / 2;
+ _mouse.x -= (kHercWidth - _screenWidth * 2) / 2;
_mouse.x >>= 1;
_mouse.y = _mouse.y * 4 / 7;
} else if (_useCJKMode && _textSurfaceMultiplier == 2) {
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index ba13ff46d9..51ba2195d7 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -48,11 +48,7 @@ uint8 *ScummEngine::getHEPaletteSlot(uint16 palSlot) {
}
uint16 ScummEngine::get16BitColor(uint8 r, uint8 g, uint8 b) {
- uint16 ar = (r >> 3) << 10;
- uint16 ag = (g >> 3) << 5;
- uint16 ab = (b >> 3) << 0;
- uint16 col = ar | ag | ab;
- return col;
+ return _outputPixelFormat.RGBToColor(r, g, b);
}
void ScummEngine::resetPalette() {
diff --git a/engines/scumm/player_towns.cpp b/engines/scumm/player_towns.cpp
index e71a8d0587..dd7630d370 100644
--- a/engines/scumm/player_towns.cpp
+++ b/engines/scumm/player_towns.cpp
@@ -32,7 +32,7 @@ Player_Towns::Player_Towns(ScummEngine *vm, bool isVersion2) : _vm(vm), _v2(isVe
void Player_Towns::setSfxVolume(int vol) {
if (!_intf)
- return;
+ return;
_intf->setSoundEffectVolume(vol);
}
@@ -98,17 +98,17 @@ void Player_Towns::playPcmTrack(int sound, const uint8 *data, int velo, int pan,
return;
const uint8 *sfxData = data + 16;
-
+
int numChan = _v2 ? 1 : data[14];
for (int i = 0; i < numChan; i++) {
int chan = allocatePcmChannel(sound, i, priority);
if (!chan)
return;
-
+
_intf->callback(70, _unkFlags);
_intf->callback(3, chan + 0x3f, pan);
_intf->callback(37, chan + 0x3f, note, velo, sfxData);
-
+
_pcmCurrentSound[chan].note = note;
_pcmCurrentSound[chan].velo = velo;
_pcmCurrentSound[chan].pan = pan;
@@ -191,7 +191,7 @@ Player_Towns_v1::Player_Towns_v1(ScummEngine *vm, Audio::Mixer *mixer) : Player_
if (_vm->_game.version == 3) {
_soundOverride = new SoundOvrParameters[_numSoundMax];
memset(_soundOverride, 0, _numSoundMax * sizeof(SoundOvrParameters));
- }
+ }
_driver = new TownsEuphonyDriver(mixer);
}
@@ -204,7 +204,7 @@ Player_Towns_v1::~Player_Towns_v1() {
bool Player_Towns_v1::init() {
if (!_driver)
return false;
-
+
if (!_driver->init())
return false;
@@ -235,13 +235,13 @@ void Player_Towns_v1::startSound(int sound) {
if (type == 0) {
uint8 velocity = 0;
uint8 note = 0;
-
+
if (_vm->_game.version == 3) {
velocity = (_soundOverride[sound].vLeft + _soundOverride[sound].vRight);
note = _soundOverride[sound].note;
}
- velocity = velocity ? velocity >> 2 : ptr[14] >> 1;
+ velocity = velocity ? velocity >> 2 : ptr[14] >> 1;
playPcmTrack(sound, ptr + 6, velocity, 64, note ? note : ptr[50], READ_LE_UINT16(ptr + 10));
} else if (type == 1) {
@@ -267,7 +267,7 @@ void Player_Towns_v1::stopSound(int sound) {
_eupLooping = false;
_driver->stopParser();
}
-
+
stopPcmTrack(sound);
}
@@ -293,7 +293,7 @@ int Player_Towns_v1::getSoundStatus(int sound) const {
int32 Player_Towns_v1::doCommand(int numargs, int args[]) {
int32 res = 0;
-
+
switch (args[0]) {
case 2:
_driver->intf()->callback(73, 0);
@@ -381,12 +381,12 @@ void Player_Towns_v1::saveLoadWithSerializer(Serializer *ser) {
void Player_Towns_v1::restoreAfterLoad() {
setVolumeCD(_cdaVolLeft, _cdaVolRight);
-
+
if (_cdaCurrentSoundTemp) {
uint8 *ptr = _vm->getResourceAddress(rtSound, _cdaCurrentSoundTemp) + 6;
if (_vm->_game.version != 3)
ptr += 2;
-
+
if (ptr[7] == 2) {
playCdaTrack(_cdaCurrentSoundTemp, ptr, true);
_cdaCurrentSound = _cdaCurrentSoundTemp;
@@ -398,7 +398,7 @@ void Player_Towns_v1::restoreAfterLoad() {
uint8 *ptr = _vm->getResourceAddress(rtSound, _eupCurrentSound) + 6;
if (_vm->_game.version != 3)
ptr += 2;
-
+
if (ptr[7] == 1) {
setSoundVolume(_eupCurrentSound, _eupVolLeft, _eupVolRight);
playEuphonyTrack(_eupCurrentSound, ptr);
@@ -458,7 +458,7 @@ void Player_Towns_v1::startSoundEx(int sound, int velo, int pan, int note) {
} else if (ptr[13] == 2) {
int volLeft = velo;
int volRight = velo;
-
+
if (pan < 50)
volRight = ((pan * 2 + 1) * velo + 50) / 100;
else if (pan > 50)
@@ -478,7 +478,7 @@ void Player_Towns_v1::stopSoundSuspendLooping(int sound) {
return;
} else if (sound == _cdaCurrentSound) {
if (_cdaNumLoops && _cdaForceRestart)
- _cdaForceRestart = 1;
+ _cdaForceRestart = 1;
} else {
for (int i = 1; i < 9; i++) {
if (sound == _pcmCurrentSound[i].index) {
@@ -487,7 +487,7 @@ void Player_Towns_v1::stopSoundSuspendLooping(int sound) {
_driver->stopSoundEffect(i + 0x3f);
if (_pcmCurrentSound[i].looping)
_pcmCurrentSound[i].paused = 1;
- else
+ else
_pcmCurrentSound[i].index = 0;
}
}
@@ -532,7 +532,7 @@ void Player_Towns_v1::playEuphonyTrack(int sound, const uint8 *data) {
uint32 trackSize = READ_LE_UINT32(src);
src += 4;
uint8 startTick = *src++;
-
+
_driver->setMusicTempo(*src++);
_driver->startMusicTrack(trackData, trackSize, startTick);
@@ -559,7 +559,7 @@ void Player_Towns_v1::playCdaTrack(int sound, const uint8 *data, bool skipTrackV
}
}
- if (sound == _cdaCurrentSound && _vm->_sound->pollCD() == 1)
+ if (sound == _cdaCurrentSound && _vm->_sound->pollCD() == 1)
return;
ptr += 16;
@@ -585,7 +585,7 @@ Player_Towns_v2::~Player_Towns_v2() {
_intf = 0;
if (_imuseDispose)
- delete _imuse;
+ delete _imuse;
delete[] _sblData;
delete[] _soundOverride;
@@ -594,7 +594,7 @@ Player_Towns_v2::~Player_Towns_v2() {
bool Player_Towns_v2::init() {
if (!_intf)
return false;
-
+
if (!_intf->init())
return false;
@@ -637,7 +637,7 @@ void Player_Towns_v2::startSound(int sound) {
void Player_Towns_v2::stopSound(int sound) {
if (_soundOverride[sound].type == 7) {
- stopPcmTrack(sound);
+ stopPcmTrack(sound);
} else {
_imuse->stopSound(sound);
}
@@ -651,7 +651,7 @@ void Player_Towns_v2::stopAllSounds() {
int32 Player_Towns_v2::doCommand(int numargs, int args[]) {
int32 res = -1;
uint8 *ptr = 0;
-
+
switch (args[0]) {
case 8:
startSound(args[1]);
@@ -675,7 +675,7 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) {
case 258:
if (_soundOverride[args[1]].type == 0) {
ptr = _vm->getResourceAddress(rtSound, args[1]);
- if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S'))
+ if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S'))
_soundOverride[args[1]].type = 7;
}
if (_soundOverride[args[1]].type == 7) {
@@ -683,11 +683,11 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) {
res = 0;
}
break;
-
+
case 259:
if (_soundOverride[args[1]].type == 0) {
ptr = _vm->getResourceAddress(rtSound, args[1]);
- if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S'))
+ if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S'))
_soundOverride[args[1]].type = 7;
}
if (_soundOverride[args[1]].type == 7) {
@@ -702,7 +702,7 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) {
if (res == -1)
return _imuse->doCommand(numargs, args);
-
+
return res;
}
@@ -718,9 +718,9 @@ void Player_Towns_v2::playVocTrack(const uint8 *data) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x04, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00
};
-
+
uint32 len = (READ_LE_UINT32(data) >> 8) - 2;
-
+
int chan = allocatePcmChannel(0xffff, 0, 0x1000);
if (!chan)
return;
diff --git a/engines/scumm/player_towns.h b/engines/scumm/player_towns.h
index 470020d621..5c76d7c6c7 100644
--- a/engines/scumm/player_towns.h
+++ b/engines/scumm/player_towns.h
@@ -47,8 +47,8 @@ public:
virtual void restoreAfterLoad();
// version 1 specific
- virtual int getCurrentCdaSound() { return 0; }
- virtual int getCurrentCdaVolume() { return 0; }
+ virtual int getCurrentCdaSound() { return 0; }
+ virtual int getCurrentCdaVolume() { return 0; }
virtual void setVolumeCD(int left, int right) {}
virtual void setSoundVolume(int sound, int left, int right) {}
virtual void setSoundNote(int sound, int note) {}
@@ -92,8 +92,8 @@ public:
void stopAllSounds();
int getSoundStatus(int sound) const;
- int getCurrentCdaSound() { return _cdaCurrentSound; }
- int getCurrentCdaVolume() { return (_cdaVolLeft + _cdaVolRight + 1) >> 1; }
+ int getCurrentCdaSound() { return _cdaCurrentSound; }
+ int getCurrentCdaVolume() { return (_cdaVolLeft + _cdaVolRight + 1) >> 1; }
int32 doCommand(int numargs, int args[]);
@@ -124,7 +124,7 @@ private:
uint8 _cdaVolLeft;
uint8 _cdaVolRight;
-
+
uint8 _eupCurrentSound;
uint8 _eupLooping;
uint8 _eupVolLeft;
@@ -170,7 +170,7 @@ private:
SoundOvrParameters *_soundOverride;
uint8 *_sblData;
-
+
IMuse *_imuse;
const bool _imuseDispose;
};
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 0448f60593..10301da3e3 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -822,11 +822,12 @@ byte *ResourceManager::createResource(ResType type, ResId idx, uint32 size) {
expireResources(size);
- byte *ptr = (byte *)calloc(size + SAFETY_AREA, 1);
+ byte *ptr = new byte[size + SAFETY_AREA];
if (ptr == NULL) {
error("createResource(%s,%d): Out of memory while allocating %d", nameOfResType(type), idx, size);
}
+ memset(ptr, 0, size + SAFETY_AREA);
_allocatedSize += size;
_types[type][idx]._address = ptr;
@@ -845,12 +846,12 @@ ResourceManager::Resource::Resource() {
}
ResourceManager::Resource::~Resource() {
- delete _address;
+ delete[] _address;
_address = 0;
}
void ResourceManager::Resource::nuke() {
- delete _address;
+ delete[] _address;
_address = 0;
_size = 0;
_flags = 0;
diff --git a/engines/scumm/resource.h b/engines/scumm/resource.h
index e8b0c1eaae..2e8960717f 100644
--- a/engines/scumm/resource.h
+++ b/engines/scumm/resource.h
@@ -63,9 +63,9 @@ class ScummEngine;
* marked in this way.
*/
enum ResTypeMode {
- kDynamicResTypeMode = 0, ///!< Resource is generated during runtime and may change
- kStaticResTypeMode = 1, ///!< Resource comes from data files, does not change
- kSoundResTypeMode = 2 ///!< Resource comes from data files, but may change
+ kDynamicResTypeMode = 0, ///< Resource is generated during runtime and may change
+ kStaticResTypeMode = 1, ///< Resource comes from data files, does not change
+ kSoundResTypeMode = 2 ///< Resource comes from data files, but may change
};
/**
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 19834cb35d..3cc710c207 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1316,10 +1316,10 @@ void ScummEngine::saveOrLoad(Serializer *s) {
MKEND()
};
- s->saveLoadArrayOf(_textPalette, 48, sizeof(_textPalette[0]), sleUint8);
+ s->saveLoadArrayOf(_textPalette, 48, sizeof(_textPalette[0]), sleUint8);
s->saveLoadArrayOf(_cyclRects, 10, sizeof(_cyclRects[0]), townsFields);
s->saveLoadArrayOf(&_curStringRect, 1, sizeof(_curStringRect), townsFields);
- s->saveLoadArrayOf(_townsCharsetColorMap, 16, sizeof(_townsCharsetColorMap[0]), sleUint8);
+ s->saveLoadArrayOf(_townsCharsetColorMap, 16, sizeof(_townsCharsetColorMap[0]), sleUint8);
s->saveLoadEntries(this, townsExtraEntries);
}
#endif
@@ -1489,7 +1489,7 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
// Reset cursors for old FM-Towns savegames saved with 256 color setting.
// Otherwise the cursor will be messed up when displayed in the new hi color setting.
- if (_game.platform == Common::kPlatformFMTowns && _bytesPerPixelOutput == 2 && s->isLoading() && s->getVersion() < VER(82)) {
+ if (_game.platform == Common::kPlatformFMTowns && _outputPixelFormat.bytesPerPixel == 2 && s->isLoading() && s->getVersion() < VER(82)) {
if (_game.id == GID_LOOM) {
redefineBuiltinCursorFromChar(1, 1);
redefineBuiltinCursorHotspot(1, 0, 0);
@@ -1497,6 +1497,16 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
resetCursors();
}
}
+
+ // Regenerate 16bit palette after loading.
+ // This avoids color issues when loading savegames that have been saved with a different ScummVM port
+ // that uses a different 16bit color mode than the ScummVM port which is currently used.
+#ifdef USE_RGB_COLOR
+ if (_game.platform == Common::kPlatformPCEngine && s->isLoading()) {
+ for (int i = 0; i < 256; ++i)
+ _16BitPalette[i] = get16BitColor(_currentPalette[i * 3 + 0], _currentPalette[i * 3 + 1], _currentPalette[i * 3 + 2]);
+ }
+#endif
}
#ifdef ENABLE_SCUMM_7_8
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 2c8f65496f..a6cf504586 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1611,7 +1611,7 @@ void ScummEngine_v5::o5_resourceRoutines() {
foo = getVarOrDirectByte(PARAM_2);
bar = fetchScriptByte();
if (_townsPlayer)
- _townsPlayer->setSoundVolume(resid, foo, bar);
+ _townsPlayer->setSoundVolume(resid, foo, bar);
break;
case 37:
if (_townsPlayer)
@@ -2319,7 +2319,7 @@ void ScummEngine_v5::o5_verbOps() {
if (_game.platform == Common::kPlatformFMTowns && _game.version == 3 && slot)
continue;
-
+
if (slot == 0) {
for (slot = 1; slot < _numVerbs; slot++) {
if (_verbs[slot].verbid == 0)
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 36caff452d..7b136dc36d 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -114,17 +114,18 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_rnd("scumm")
{
- if (_game.heversion > 0) {
- _gdi = new GdiHE(this);
- } else if (_game.platform == Common::kPlatformNES) {
- _gdi = new GdiNES(this);
#ifdef USE_RGB_COLOR
- } else if (_game.features & GF_16BIT_COLOR) {
+ if (_game.features & GF_16BIT_COLOR) {
if (_game.platform == Common::kPlatformPCEngine)
_gdi = new GdiPCEngine(this);
- else
- _gdi = new Gdi16Bit(this);
+ else if (_game.heversion > 0)
+ _gdi = new GdiHE16bit(this);
+ } else
#endif
+ if (_game.heversion > 0) {
+ _gdi = new GdiHE(this);
+ } else if (_game.platform == Common::kPlatformNES) {
+ _gdi = new GdiNES(this);
} else if (_game.version <= 1) {
_gdi = new GdiV1(this);
} else if (_game.version == 2) {
@@ -162,7 +163,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_pauseDialog = NULL;
_versionDialog = NULL;
_fastMode = 0;
- _actors = NULL;
+ _actors = _sortedActors = NULL;
_arraySlot = NULL;
_inventory = NULL;
_newNames = NULL;
@@ -260,7 +261,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_switchRoomEffect2 = 0;
_switchRoomEffect = 0;
- _bytesPerPixelOutput = _bytesPerPixel = 1;
+ _bytesPerPixel = 1;
_doEffect = false;
_snapScroll = false;
_currentLights = 0;
@@ -328,7 +329,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
memset(&_cyclRects, 0, 16 * sizeof(Common::Rect));
_numCyclRects = 0;
#endif
-
+
//
// Init all VARS to 0xFF
//
@@ -545,24 +546,25 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_screenHeight = 200;
}
- _bytesPerPixelOutput = _bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
+ _bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
+ uint8 sizeMult = _bytesPerPixel;
#ifdef USE_RGB_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_game.platform == Common::kPlatformFMTowns)
- _bytesPerPixelOutput = 2;
+ sizeMult = 2;
#endif
#endif
// Allocate gfx compositing buffer (not needed for V7/V8 games).
if (_game.version < 7)
- _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight * _bytesPerPixelOutput);
+ _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight * sizeMult);
else
_compositeBuf = 0;
_herculesBuf = 0;
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- _herculesBuf = (byte *)malloc(Common::kHercW * Common::kHercH);
+ _herculesBuf = (byte *)malloc(kHercWidth * kHercHeight);
}
// Add debug levels
@@ -584,9 +586,12 @@ ScummEngine::~ScummEngine() {
_mixer->stopAll();
- for (int i = 0; i < _numActors; ++i)
- delete _actors[i];
- delete[] _actors;
+ if (_actors) {
+ for (int i = 0; i < _numActors; ++i)
+ delete _actors[i];
+ delete[] _actors;
+ }
+
delete[] _sortedActors;
delete[] _2byteFontPtr;
@@ -1135,7 +1140,7 @@ Common::Error ScummEngine::init() {
// Initialize backend
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- initGraphics(Common::kHercW, Common::kHercH, true);
+ initGraphics(kHercWidth, kHercHeight, true);
} else {
int screenWidth = _screenWidth;
int screenHeight = _screenHeight;
@@ -1145,16 +1150,37 @@ Common::Error ScummEngine::init() {
screenWidth *= _textSurfaceMultiplier;
screenHeight *= _textSurfaceMultiplier;
}
- if (_game.features & GF_16BIT_COLOR
+ if (_game.features & GF_16BIT_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
|| _game.platform == Common::kPlatformFMTowns
#endif
) {
#ifdef USE_RGB_COLOR
- Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
- initGraphics(screenWidth, screenHeight, screenWidth > 320, &format);
- if (format != _system->getScreenFormat())
- return Common::kUnsupportedColorMode;
+ _outputPixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+
+ if (_game.platform != Common::kPlatformFMTowns && _game.platform != Common::kPlatformPCEngine) {
+ initGraphics(screenWidth, screenHeight, screenWidth > 320, &_outputPixelFormat);
+ if (_outputPixelFormat != _system->getScreenFormat())
+ return Common::kUnsupportedColorMode;
+ } else {
+ Common::List<Graphics::PixelFormat> tryModes = _system->getSupportedFormats();
+ for (Common::List<Graphics::PixelFormat>::iterator g = tryModes.begin(); g != tryModes.end(); ++g) {
+ if (g->bytesPerPixel != 2 || g->aBits()) {
+ g = tryModes.erase(g);
+ g--;
+ }
+
+ if (*g == _outputPixelFormat) {
+ tryModes.clear();
+ tryModes.push_back(_outputPixelFormat);
+ break;
+ }
+ }
+
+ initGraphics(screenWidth, screenHeight, screenWidth > 320, tryModes);
+ if (_system->getScreenFormat().bytesPerPixel != 2)
+ return Common::kUnsupportedColorMode;
+ }
#else
if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) {
warning("Starting game without the required 16bit color support.\nYou may experience color glitches");
@@ -1166,12 +1192,14 @@ Common::Error ScummEngine::init() {
} else {
#ifdef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_game.platform == Common::kPlatformFMTowns && _game.version == 5)
- error("This game requires dual graphics layer support which is disabled in this build");
+ return Common::Error(Common::kUnsupportedColorMode, "This game requires dual graphics layer support which is disabled in this build");
#endif
initGraphics(screenWidth, screenHeight, (screenWidth > 320));
}
}
+ _outputPixelFormat = _system->getScreenFormat();
+
setupScumm();
readIndexFile();
@@ -1280,7 +1308,7 @@ void ScummEngine::setupScumm() {
_res->setHeapThreshold(400000, maxHeapThreshold);
free(_compositeBuf);
- _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _bytesPerPixelOutput);
+ _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _outputPixelFormat.bytesPerPixel);
}
#ifdef ENABLE_SCUMM_7_8
@@ -1361,7 +1389,7 @@ void ScummEngine::resetScumm() {
#ifdef USE_RGB_COLOR
if (_game.features & GF_16BIT_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
- || _game.platform == Common::kPlatformFMTowns
+ || (_game.platform == Common::kPlatformFMTowns)
#endif
)
_16BitPalette = (uint16 *)calloc(512, sizeof(uint16));
@@ -1370,8 +1398,8 @@ void ScummEngine::resetScumm() {
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_game.platform == Common::kPlatformFMTowns) {
delete _townsScreen;
- _townsScreen = new TownsScreen(_system, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, _bytesPerPixelOutput);
- _townsScreen->setupLayer(0, _screenWidth, _screenHeight, (_bytesPerPixelOutput == 2) ? 32767 : 256);
+ _townsScreen = new TownsScreen(_system, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, _outputPixelFormat);
+ _townsScreen->setupLayer(0, _screenWidth, _screenHeight, (_outputPixelFormat.bytesPerPixel == 2) ? 32767 : 256);
_townsScreen->setupLayer(1, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, 16, _textPalette);
}
#endif
@@ -1762,8 +1790,10 @@ void ScummEngine::setupMusic(int midi) {
if (missingFile) {
GUI::MessageDialog dialog(
- "Native MIDI support requires the Roland Upgrade from LucasArts,\n"
- "but " + fileName + " is missing. Using AdLib instead.", "Ok");
+ Common::String::format(
+ _("Native MIDI support requires the Roland Upgrade from LucasArts,\n"
+ "but %s is missing. Using AdLib instead."), fileName.c_str()),
+ _("OK"));
dialog.runModal();
_musicType = MDT_ADLIB;
}
@@ -1838,7 +1868,7 @@ void ScummEngine::setupMusic(int midi) {
}
_imuse = IMuse::create(_system, nativeMidiDriver, adlibMidiDriver);
-
+
if (_game.platform == Common::kPlatformFMTowns) {
_musicEngine = _townsPlayer = new Player_Towns_v2(this, _mixer, _imuse, true);
if (!_townsPlayer->init())
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 6e75f47d77..01bde90e1c 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -897,7 +897,7 @@ public:
Common::RenderMode _renderMode;
uint8 _bytesPerPixel;
- uint8 _bytesPerPixelOutput;
+ Graphics::PixelFormat _outputPixelFormat;
protected:
ColorCycle _colorCycle[16]; // Palette cycles
@@ -1004,7 +1004,7 @@ protected:
// Screen rendering
byte *_compositeBuf;
byte *_herculesBuf;
-
+
virtual void drawDirtyScreenParts();
void updateDirtyScreen(VirtScreenNumber slot);
void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
@@ -1148,7 +1148,7 @@ protected:
void restoreCharsetBg();
void clearCharsetMask();
void clearTextSurface();
-
+
virtual void initCharset(int charset);
virtual void printString(int m, const byte *msg);
@@ -1348,10 +1348,10 @@ protected:
Common::Rect _cyclRects[16];
int _numCyclRects;
-
+
Common::Rect _curStringRect;
- byte _townsOverrideShadowColor;
+ byte _townsOverrideShadowColor;
byte _textPalette[48];
byte _townsClearLayerFlag;
byte _townsActiveLayerFlags;
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 66502572de..2f4e86bf61 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -90,13 +90,13 @@ public:
assert(def_end != NULL);
char *id_end = def_end;
- while (id_end >= def_start && !isdigit(*(id_end-1))) {
+ while (id_end >= def_start && !isdigit(static_cast<unsigned char>(*(id_end-1)))) {
id_end--;
}
assert(id_end > def_start);
char *id_start = id_end;
- while (isdigit(*(id_start - 1))) {
+ while (isdigit(static_cast<unsigned char>(*(id_start - 1)))) {
id_start--;
}
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index c22da8e7c7..27e43b3740 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -312,7 +312,7 @@ void Sound::playSound(int soundID) {
sound = (byte *)malloc(size);
memcpy(sound, ptr + 6, size);
stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
}
else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKTAG('S','O','U','N')) {
if (_vm->_game.version != 3)
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index 4b3207c6bf..2d2209c155 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -1383,10 +1383,10 @@ void ScummEngine_v7::loadLanguageBundle() {
} else if (*ptr == '#') {
// Number of subtags following a given basetag. We don't need that
// information so we just skip it
- } else if (isdigit(*ptr)) {
+ } else if (isdigit(static_cast<unsigned char>(*ptr))) {
int idx = 0;
// A number (up to three digits)...
- while (isdigit(*ptr)) {
+ while (isdigit(static_cast<unsigned char>(*ptr))) {
idx = idx * 10 + (*ptr - '0');
ptr++;
}
@@ -1424,12 +1424,12 @@ void ScummEngine_v7::loadLanguageBundle() {
for (i = 0; i < _languageIndexSize; i++) {
// First 8 chars in the line give the string ID / 'tag'
int j;
- for (j = 0; j < 8 && !isspace(*ptr); j++, ptr++)
+ for (j = 0; j < 8 && !isspace(static_cast<unsigned char>(*ptr)); j++, ptr++)
_languageIndex[i].tag[j] = toupper(*ptr);
_languageIndex[i].tag[j] = 0;
// After that follows a single space which we skip
- assert(isspace(*ptr));
+ assert(isspace(static_cast<unsigned char>(*ptr)));
ptr++;
// Then comes the translated string: we record an offset to that.
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 69caceb53a..0c1554840e 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -152,7 +152,7 @@ void ScummEngine_v0::setNewKidVerbs() {
void ScummEngine_v0::switchActor(int slot) {
resetSentence(false);
-
+
if (_currentRoom == 45)
return;
@@ -728,7 +728,7 @@ void ScummEngine_v0::runObject(int obj, int entry) {
entry = 0x0F;
}
}
-
+
_v0ObjectInInventory = prev;
if (getVerbEntrypoint(obj, entry) != 0) {
@@ -830,7 +830,7 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
} else {
_verbPickup = false;
}
-
+
// Ignore verbs?
Actor *a = derefActor(VAR(VAR_EGO), "verbObtain");
if (((ActorC64 *)a)->_miscflags & 0x40) {
@@ -989,7 +989,7 @@ bool ScummEngine_v0::verbExec() {
runObject(_activeObjectIndex, entry);
_v0ObjectIndex = false;
} else if (_activeInventory) {
- // Not sure this is the correct way to do this,
+ // Not sure this is the correct way to do this,
// however its working for most situations - segra
if (verbExecutes(_activeInventory, true) == false) {
if (_activeObject2 && _activeObject2Inv && verbExecutes(_activeObject2, true)) {
@@ -1001,7 +1001,7 @@ bool ScummEngine_v0::verbExec() {
runObject(_activeObject, _activeVerb);
} else {
_v0ObjectInInventory = true;
-
+
if (_activeObject2) {
_activeObject = _activeObject2;
@@ -1085,7 +1085,7 @@ void ScummEngine_v0::checkExecVerbs() {
// Click into V2 inventory
checkV2Inventory(_mouse.x, _mouse.y);
-
+
// Did the Inventory position changed (arrows pressed, do nothing)
if (invOff != _inventoryOffset)
return;
@@ -1143,7 +1143,7 @@ void ScummEngine_v0::checkExecVerbs() {
obj = 0;
objIdx = 0;
}
-
+
if (a->_miscflags & 0x80) {
if (_activeVerb != 7 && over != 7) {
_activeVerb = 0;
@@ -1444,9 +1444,9 @@ void ScummEngine::restoreVerbBG(int verb) {
VerbSlot *vs;
vs = &_verbs[verb];
- uint8 col =
+ uint8 col =
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
- ((_game.platform == Common::kPlatformFMTowns) && (_game.id == GID_MONKEY2 || _game.id == GID_INDY4) && (vs->bkcolor == _townsOverrideShadowColor)) ? 0 :
+ ((_game.platform == Common::kPlatformFMTowns) && (_game.id == GID_MONKEY2 || _game.id == GID_INDY4) && (vs->bkcolor == _townsOverrideShadowColor)) ? 0 :
#endif
vs->bkcolor;
diff --git a/engines/sky/compact.cpp b/engines/sky/compact.cpp
index 66ce92f8fc..84609d5500 100644
--- a/engines/sky/compact.cpp
+++ b/engines/sky/compact.cpp
@@ -25,6 +25,7 @@
#include "common/endian.h"
#include "common/file.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "sky/compact.h"
#include "gui/message.h"
#include <stddef.h> // for ptrdiff_t
@@ -126,8 +127,8 @@ static const uint32 turnTableOffsets[] = {
SkyCompact::SkyCompact() {
_cptFile = new Common::File();
if (!_cptFile->open("sky.cpt")) {
- GUI::MessageDialog dialog("Unable to find \"sky.cpt\" file!\n"
- "Please download it from www.scummvm.org", "OK", NULL);
+ GUI::MessageDialog dialog(_("Unable to find \"sky.cpt\" file!\n"
+ "Please download it from www.scummvm.org"), _("OK"), NULL);
dialog.runModal();
error("Unable to find \"sky.cpt\" file\nPlease download it from www.scummvm.org");
}
@@ -137,7 +138,7 @@ SkyCompact::SkyCompact() {
error("unknown \"sky.cpt\" version");
if (SKY_CPT_SIZE != _cptFile->size()) {
- GUI::MessageDialog dialog("The \"sky.cpt\" file has an incorrect size.\nPlease (re)download it from www.scummvm.org", "OK", NULL);
+ GUI::MessageDialog dialog(_("The \"sky.cpt\" file has an incorrect size.\nPlease (re)download it from www.scummvm.org"), _("OK"), NULL);
dialog.runModal();
error("Incorrect sky.cpt size (%d, expected: %d)", _cptFile->size(), SKY_CPT_SIZE);
}
diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp
index f3cce06ad6..a1067496da 100644
--- a/engines/sky/detection.cpp
+++ b/engines/sky/detection.cpp
@@ -206,7 +206,7 @@ SaveStateList SkyMetaEngine::listSaves(const char *target) const {
// Extract the extension
Common::String ext = file->c_str() + file->size() - 3;
ext.toUppercase();
- if (isdigit(ext[0]) && isdigit(ext[1]) && isdigit(ext[2])){
+ if (isdigit(static_cast<unsigned char>(ext[0])) && isdigit(static_cast<unsigned char>(ext[1])) && isdigit(static_cast<unsigned char>(ext[2]))){
int slotNum = atoi(ext.c_str());
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 7e9d1142be..f19efd2635 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -24,6 +24,7 @@
#include "common/events.h"
#include "common/keyboard.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "sword1/sword1.h"
#include "sword1/animation.h"
#include "sword1/text.h"
@@ -113,7 +114,7 @@ bool MoviePlayer::load(uint32 id) {
int startFrame = strtoul(ptr, const_cast<char **>(&ptr), 10);
int endFrame = strtoul(ptr, const_cast<char **>(&ptr), 10);
- while (*ptr && isspace(*ptr))
+ while (*ptr && isspace(static_cast<unsigned char>(*ptr)))
ptr++;
if (startFrame > endFrame) {
@@ -260,7 +261,7 @@ bool MoviePlayer::playVideo() {
uint32 minWeight = 0xFFFFFFFF;
uint32 weight;
byte r, g, b;
-
+
const byte *palette = _decoder->getPalette();
for (int i = 0; i < 256; i++) {
@@ -324,7 +325,6 @@ uint32 DXADecoderWithSound::getElapsedTime() const {
MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system) {
Common::String filename;
- char buf[60];
Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle;
filename = Common::String::format("%s.smk", sequenceList[id]);
@@ -341,7 +341,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M
DXADecoderWithSound *dxaDecoder = new DXADecoderWithSound(snd, bgSoundHandle);
return new MoviePlayer(vm, textMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA);
#else
- GUI::MessageDialog dialog("DXA cutscenes found but ScummVM has been built without zlib support", "OK");
+ GUI::MessageDialog dialog(_("DXA cutscenes found but ScummVM has been built without zlib support"), _("OK"));
dialog.runModal();
return NULL;
#endif
@@ -351,13 +351,13 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M
filename = Common::String::format("%s.mp2", sequenceList[id]);
if (Common::File::exists(filename)) {
- GUI::MessageDialog dialog("MPEG2 cutscenes are no longer supported", "OK");
+ GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK"));
dialog.runModal();
return NULL;
}
- sprintf(buf, "Cutscene '%s' not found", sequenceList[id]);
- GUI::MessageDialog dialog(buf, "OK");
+ Common::String buf = Common::String::format(_("Cutscene '%s' not found"), sequenceList[id]);
+ GUI::MessageDialog dialog(buf, _("OK"));
dialog.runModal();
return NULL;
diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 86947db8ae..36d5a24e99 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -27,6 +27,7 @@
#include "common/system.h"
#include "common/config-manager.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "graphics/palette.h"
#include "graphics/thumbnail.h"
@@ -859,9 +860,9 @@ void Control::checkForOldSaveGames() {
}
GUI::MessageDialog dialog0(
- "ScummVM found that you have old savefiles for Broken Sword 1 that should be converted.\n"
+ _("ScummVM found that you have old savefiles for Broken Sword 1 that should be converted.\n"
"The old save game format is no longer supported, so you will not be able to load your games if you don't convert them.\n\n"
- "Press OK to convert them now, otherwise you will be asked again the next time you start the game.\n", "OK", "Cancel");
+ "Press OK to convert them now, otherwise you will be asked again the next time you start the game.\n"), _("OK"), _("Cancel"));
int choice = dialog0.runModal();
if (choice == GUI::kMessageCancel) {
@@ -1228,11 +1229,10 @@ bool Control::convertSaveGame(uint8 slot, char* desc) {
if (testSave) {
delete testSave;
- char msg[200];
- sprintf(msg, "Target new save game already exists!\n"
- "Would you like to keep the old save game (%s) or the new one (%s)?\n",
+ Common::String msg = Common::String::format(_("Target new save game already exists!\n"
+ "Would you like to keep the old save game (%s) or the new one (%s)?\n"),
oldFileName, newFileName);
- GUI::MessageDialog dialog0(msg, "Keep the old one", "Keep the new one");
+ GUI::MessageDialog dialog0(msg, _("Keep the old one"), _("Keep the new one"));
int choice = dialog0.runModal();
if (choice == GUI::kMessageCancel) {
diff --git a/engines/sword1/detection.cpp b/engines/sword1/detection.cpp
index 48c3a0d14d..0c1e74082f 100644
--- a/engines/sword1/detection.cpp
+++ b/engines/sword1/detection.cpp
@@ -33,18 +33,18 @@
#include "engines/metaengine.h"
/* Broken Sword */
-static const PlainGameDescriptorGUIOpts sword1FullSettings =
- {"sword1", "Broken Sword: The Shadow of the Templars", Common::GUIO_NOMIDI};
-static const PlainGameDescriptorGUIOpts sword1DemoSettings =
- {"sword1demo", "Broken Sword: The Shadow of the Templars (Demo)", Common::GUIO_NOMIDI};
-static const PlainGameDescriptorGUIOpts sword1MacFullSettings =
- {"sword1mac", "Broken Sword: The Shadow of the Templars (Mac)", Common::GUIO_NOMIDI};
-static const PlainGameDescriptorGUIOpts sword1MacDemoSettings =
- {"sword1macdemo", "Broken Sword: The Shadow of the Templars (Mac demo)", Common::GUIO_NOMIDI};
-static const PlainGameDescriptorGUIOpts sword1PSXSettings =
- {"sword1psx", "Broken Sword: The Shadow of the Templars (PlayStation)", Common::GUIO_NOMIDI};
-static const PlainGameDescriptorGUIOpts sword1PSXDemoSettings =
- {"sword1psxdemo", "Broken Sword: The Shadow of the Templars (PlayStation demo)", Common::GUIO_NOMIDI};
+static const PlainGameDescriptor sword1FullSettings =
+ {"sword1", "Broken Sword: The Shadow of the Templars"};
+static const PlainGameDescriptor sword1DemoSettings =
+ {"sword1demo", "Broken Sword: The Shadow of the Templars (Demo)"};
+static const PlainGameDescriptor sword1MacFullSettings =
+ {"sword1mac", "Broken Sword: The Shadow of the Templars (Mac)"};
+static const PlainGameDescriptor sword1MacDemoSettings =
+ {"sword1macdemo", "Broken Sword: The Shadow of the Templars (Mac demo)"};
+static const PlainGameDescriptor sword1PSXSettings =
+ {"sword1psx", "Broken Sword: The Shadow of the Templars (PlayStation)"};
+static const PlainGameDescriptor sword1PSXDemoSettings =
+ {"sword1psxdemo", "Broken Sword: The Shadow of the Templars (PlayStation demo)"};
// check these subdirectories (if present)
@@ -117,12 +117,12 @@ bool Sword1::SwordEngine::hasFeature(EngineFeature f) const {
GameList SwordMetaEngine::getSupportedGames() const {
GameList games;
- games.push_back(sword1FullSettings);
- games.push_back(sword1DemoSettings);
- games.push_back(sword1MacFullSettings);
- games.push_back(sword1MacDemoSettings);
- games.push_back(sword1PSXSettings);
- games.push_back(sword1PSXDemoSettings);
+ games.push_back(GameDescriptor(sword1FullSettings, Common::GUIO_NOMIDI));
+ games.push_back(GameDescriptor(sword1DemoSettings, Common::GUIO_NOMIDI));
+ games.push_back(GameDescriptor(sword1MacFullSettings, Common::GUIO_NOMIDI));
+ games.push_back(GameDescriptor(sword1MacDemoSettings, Common::GUIO_NOMIDI));
+ games.push_back(GameDescriptor(sword1PSXSettings, Common::GUIO_NOMIDI));
+ games.push_back(GameDescriptor(sword1PSXDemoSettings, Common::GUIO_NOMIDI));
return games;
}
@@ -198,17 +198,17 @@ GameList SwordMetaEngine::detectGames(const Common::FSList &fslist) const {
psxDemoFilesFound = false;
if (mainFilesFound && pcFilesFound && demoFilesFound)
- detectedGames.push_back(sword1DemoSettings);
+ detectedGames.push_back(GameDescriptor(sword1DemoSettings, Common::GUIO_NOMIDI));
else if (mainFilesFound && pcFilesFound && psxFilesFound)
- detectedGames.push_back(sword1PSXSettings);
+ detectedGames.push_back(GameDescriptor(sword1PSXSettings, Common::GUIO_NOMIDI));
else if (mainFilesFound && pcFilesFound && psxDemoFilesFound)
- detectedGames.push_back(sword1PSXDemoSettings);
+ detectedGames.push_back(GameDescriptor(sword1PSXDemoSettings, Common::GUIO_NOMIDI));
else if (mainFilesFound && pcFilesFound && !psxFilesFound)
- detectedGames.push_back(sword1FullSettings);
+ detectedGames.push_back(GameDescriptor(sword1FullSettings, Common::GUIO_NOMIDI));
else if (mainFilesFound && macFilesFound)
- detectedGames.push_back(sword1MacFullSettings);
+ detectedGames.push_back(GameDescriptor(sword1MacFullSettings, Common::GUIO_NOMIDI));
else if (mainFilesFound && macDemoFilesFound)
- detectedGames.push_back(sword1MacDemoSettings);
+ detectedGames.push_back(GameDescriptor(sword1MacDemoSettings, Common::GUIO_NOMIDI));
return detectedGames;
}
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index 00f7112c05..5b42c9340e 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -23,6 +23,7 @@
#include "common/endian.h"
#include "common/util.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "sword1/logic.h"
#include "sword1/text.h"
@@ -1629,7 +1630,7 @@ int Logic::fnRestartGame(Object *cpt, int32 id, int32 a, int32 b, int32 c, int32
int Logic::fnQuitGame(Object *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) {
if (SwordEngine::_systemVars.isDemo) {
- GUI::MessageDialog dialog("This is the end of the Broken Sword 1 Demo", "OK", NULL);
+ GUI::MessageDialog dialog(_("This is the end of the Broken Sword 1 Demo"), _("OK"), NULL);
dialog.runModal();
Engine::quitGame();
} else
diff --git a/engines/sword1/music.cpp b/engines/sword1/music.cpp
index a291d80f85..b4656ff89f 100644
--- a/engines/sword1/music.cpp
+++ b/engines/sword1/music.cpp
@@ -47,68 +47,65 @@ namespace Sword1 {
// These functions are only called from Music, so I'm just going to
// assume that if locking is needed it has already been taken care of.
-bool MusicHandle::play(const char *fileBase, bool loop) {
- char fileName[30];
+bool MusicHandle::play(const Common::String &filename, bool loop) {
stop();
// FIXME: How about using AudioStream::openStreamFile instead of the code below?
// I.e.:
//_audioSource = Audio::AudioStream::openStreamFile(fileBase, 0, 0, loop ? 0 : 1);
+ Audio::RewindableAudioStream *stream = 0;
+
#ifdef USE_FLAC
- if (!_audioSource) {
- sprintf(fileName, "%s.flac", fileBase);
- if (_file.open(fileName)) {
- _audioSource = Audio::makeLoopingAudioStream(Audio::makeFLACStream(&_file, DisposeAfterUse::NO), loop ? 0 : 1);
- if (!_audioSource)
+ if (!stream) {
+ if (_file.open(filename + ".flac")) {
+ stream = Audio::makeFLACStream(&_file, DisposeAfterUse::NO);
+ if (!stream)
_file.close();
}
}
- if (!_audioSource) {
- sprintf(fileName, "%s.fla", fileBase);
- if (_file.open(fileName)) {
- _audioSource = Audio::makeLoopingAudioStream(Audio::makeFLACStream(&_file, DisposeAfterUse::NO), loop ? 0 : 1);
- if (!_audioSource)
+ if (!stream) {
+ if (_file.open(filename + ".fla")) {
+ stream = Audio::makeFLACStream(&_file, DisposeAfterUse::NO);
+ if (!stream)
_file.close();
}
}
#endif
#ifdef USE_VORBIS
- if (!_audioSource) {
- sprintf(fileName, "%s.ogg", fileBase);
- if (_file.open(fileName)) {
- _audioSource = Audio::makeLoopingAudioStream(Audio::makeVorbisStream(&_file, DisposeAfterUse::NO), loop ? 0 : 1);
- if (!_audioSource)
+ if (!stream) {
+ if (_file.open(filename + ".ogg")) {
+ stream = Audio::makeVorbisStream(&_file, DisposeAfterUse::NO);
+ if (!stream)
_file.close();
}
}
#endif
#ifdef USE_MAD
- if (!_audioSource) {
- sprintf(fileName, "%s.mp3", fileBase);
- if (_file.open(fileName)) {
- _audioSource = Audio::makeLoopingAudioStream(Audio::makeMP3Stream(&_file, DisposeAfterUse::NO), loop ? 0 : 1);
- if (!_audioSource)
+ if (!stream) {
+ if (_file.open(filename + ".mp3")) {
+ stream = Audio::makeMP3Stream(&_file, DisposeAfterUse::NO);
+ if (!stream)
_file.close();
}
}
#endif
- if (!_audioSource) {
- sprintf(fileName, "%s.wav", fileBase);
- if (_file.open(fileName))
- _audioSource = Audio::makeLoopingAudioStream(Audio::makeWAVStream(&_file, DisposeAfterUse::NO), loop ? 0 : 1);
+ if (!stream) {
+ if (_file.open(filename + ".wav"))
+ stream = Audio::makeWAVStream(&_file, DisposeAfterUse::NO);
}
- if (!_audioSource) {
- sprintf(fileName, "%s.aif", fileBase);
- if (_file.open(fileName))
- _audioSource = Audio::makeLoopingAudioStream(Audio::makeAIFFStream(&_file, DisposeAfterUse::NO), loop ? 0 : 1);
+ if (!stream) {
+ if (_file.open(filename + ".aif"))
+ stream = Audio::makeAIFFStream(&_file, DisposeAfterUse::NO);
}
- if (!_audioSource)
+ if (!stream)
return false;
+ _audioSource = Audio::makeLoopingAudioStream(stream, loop ? 0 : 1);
+
fadeUp();
return true;
}
@@ -219,12 +216,9 @@ int MusicHandle::readBuffer(int16 *buffer, const int numSamples) {
}
void MusicHandle::stop() {
- if (_audioSource) {
- delete _audioSource;
- _audioSource = NULL;
- }
- if (_file.isOpen())
- _file.close();
+ delete _audioSource;
+ _audioSource = NULL;
+ _file.close();
_fading = 0;
}
diff --git a/engines/sword1/music.h b/engines/sword1/music.h
index 104bc1c536..4207019c13 100644
--- a/engines/sword1/music.h
+++ b/engines/sword1/music.h
@@ -43,7 +43,7 @@ private:
public:
MusicHandle() : _fading(0), _audioSource(NULL) {}
virtual int readBuffer(int16 *buffer, const int numSamples);
- bool play(const char *filename, bool loop);
+ bool play(const Common::String &filename, bool loop);
bool playPSX(uint16 id, bool loop);
void stop();
void fadeUp();
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 11ee4a98fd..80b4809722 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -26,6 +26,7 @@
#include "common/mutex.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "sword2/sword2.h"
#include "sword2/defs.h"
@@ -295,7 +296,7 @@ bool MoviePlayer::playVideo() {
uint32 minWeight = 0xFFFFFFFF;
uint32 weight;
byte r, g, b;
-
+
const byte *palette = _decoder->getPalette();
for (int i = 0; i < 256; i++) {
@@ -359,7 +360,6 @@ uint32 DXADecoderWithSound::getElapsedTime() const {
MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system) {
Common::String filename;
- char buf[60];
Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle;
filename = Common::String::format("%s.smk", name);
@@ -376,7 +376,7 @@ MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *s
DXADecoderWithSound *dxaDecoder = new DXADecoderWithSound(snd, bgSoundHandle);
return new MoviePlayer(vm, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA);
#else
- GUI::MessageDialog dialog("DXA cutscenes found but ScummVM has been built without zlib support", "OK");
+ GUI::MessageDialog dialog(_("DXA cutscenes found but ScummVM has been built without zlib support"), _("OK"));
dialog.runModal();
return NULL;
#endif
@@ -386,7 +386,7 @@ MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *s
filename = Common::String::format("%s.mp2", name);
if (Common::File::exists(filename)) {
- GUI::MessageDialog dialog("MPEG2 cutscenes are no longer supported", "OK");
+ GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK"));
dialog.runModal();
return NULL;
}
@@ -394,8 +394,8 @@ MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *s
// The demo tries to play some cutscenes that aren't there, so make those warnings more discreet.
// In addition, some of the later re-releases of the game don't have the "eye" Virgin logo movie.
if (!vm->_logic->readVar(DEMO) && strcmp(name, "eye") != 0) {
- sprintf(buf, "Cutscene '%s' not found", name);
- GUI::MessageDialog dialog(buf, "OK");
+ Common::String buf = Common::String::format(_("Cutscene '%s' not found"), name);
+ GUI::MessageDialog dialog(buf, _("OK"));
dialog.runModal();
} else
warning("Cutscene '%s' not found", name);
diff --git a/engines/sword25/detection.cpp b/engines/sword25/detection.cpp
index edb8c30545..b2f5795663 100644
--- a/engines/sword25/detection.cpp
+++ b/engines/sword25/detection.cpp
@@ -31,7 +31,7 @@ namespace Sword25 {
uint32 Sword25Engine::getGameFlags() const { return _gameDescription->flags; }
}
-static const PlainGameDescriptor Sword25Game[] = {
+static const PlainGameDescriptor sword25Game[] = {
{"sword25", "Broken Sword 2.5"},
{0, 0}
};
@@ -41,35 +41,13 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Sword25::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- Sword25Game,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- NULL,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOMIDI,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class Sword25MetaEngine : public AdvancedMetaEngine {
public:
- Sword25MetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ Sword25MetaEngine() : AdvancedMetaEngine(Sword25::gameDescriptions, sizeof(ADGameDescription), sword25Game) {
+ _guioptions = Common::GUIO_NOMIDI;
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "Sword25";
}
diff --git a/engines/sword25/detection_tables.h b/engines/sword25/detection_tables.h
index ca586b4f01..fe9e6e7934 100644
--- a/engines/sword25/detection_tables.h
+++ b/engines/sword25/detection_tables.h
@@ -34,7 +34,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588),
Common::EN_ANY,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -43,7 +43,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("lang_fr.b25c", "690caf157387e06d2c3d1ca53c43f428", 1006043),
Common::FR_FRA,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -52,7 +52,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588),
Common::DE_DEU,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -61,7 +61,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("lang_hr.b25c", "e881054d1f8ec1e527422fc521c25405", 1273217),
Common::HU_HUN,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -70,7 +70,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("lang_it.b25c", "f3325666da0515cc2b42062e953c0889", 996197),
Common::IT_ITA,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -79,7 +79,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("lang_pl.b25c", "49dc1a20f95391a808e475c49be2bac0", 1281799),
Common::PL_POL,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -88,7 +88,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("lang_pt.b25c", "1df701432f9e13dcefe1adeb890b9c69", 993812),
Common::PT_BRA,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -97,7 +97,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("lang_ru.b25c", "deb33dd2f90a71ff60181918a8ce5063", 1235378),
Common::RU_RUS,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
{
@@ -106,7 +106,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("lang_es.b25c", "384c19072d83725f351bb9ecb4d3f02b", 987965),
Common::ES_ESP,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NONE
},
@@ -120,7 +120,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY,
Common::kPlatformUnknown,
- GF_EXTRACTED,
+ GF_EXTRACTED | ADGF_UNSTABLE,
Common::GUIO_NONE
},
AD_TABLE_END_MARKER
diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp
index be6d940d23..a7ebb5df8c 100644
--- a/engines/sword25/fmv/theora_decoder.cpp
+++ b/engines/sword25/fmv/theora_decoder.cpp
@@ -424,6 +424,12 @@ bool TheoraDecoder::queueAudio() {
if (!_audStream)
return false;
+ // An audio buffer should have been allocated (either in the constructor or after queuing the current buffer)
+ if (!_audiobuf) {
+ warning("[TheoraDecoder::queueAudio] Invalid audio buffer");
+ return false;
+ }
+
bool queuedAudio = false;
for (;;) {
@@ -454,6 +460,11 @@ bool TheoraDecoder::queueAudio() {
// The audio mixer is now responsible for the old audio buffer.
// We need to create a new one.
_audiobuf = (ogg_int16_t *)malloc(AUDIOFD_FRAGSIZE * sizeof(ogg_int16_t));
+ if (!_audiobuf) {
+ warning("[TheoraDecoder::queueAudio] Cannot allocate memory for audio buffer");
+ return false;
+ }
+
_audiobufFill = 0;
queuedAudio = true;
}
@@ -479,12 +490,6 @@ void TheoraDecoder::reset() {
if (_fileStream)
_fileStream->seek(0);
-#if ENABLE_THEORA_SEEKING
- _videobufGranulePos = -1;
- _audiobufGranulePos = 0;
- _videobufTime = 0;
-#endif
-
_audiobufFill = 0;
_audiobufReady = false;
diff --git a/engines/sword25/gfx/animation.h b/engines/sword25/gfx/animation.h
index 55deacd333..60070be214 100644
--- a/engines/sword25/gfx/animation.h
+++ b/engines/sword25/gfx/animation.h
@@ -210,7 +210,7 @@ private:
AnimationDescription *getAnimationDescription() const;
/**
- * Initializes a new animation resource from an XML file.
+ * Initializes a new animation resource from an XML file.
*/
void initializeAnimationResource(const Common::String &fileName);
};
diff --git a/engines/sword25/gfx/animationresource.cpp b/engines/sword25/gfx/animationresource.cpp
index b9d70cf87b..621e20ad8c 100644
--- a/engines/sword25/gfx/animationresource.cpp
+++ b/engines/sword25/gfx/animationresource.cpp
@@ -64,7 +64,7 @@ AnimationResource::AnimationResource(const Common::String &filename) :
char *xmlData = _pPackage->getXmlFile(getFileName(), &fileSize);
if (!xmlData) {
error("Could not read \"%s\".", getFileName().c_str());
- return;
+ return;
}
// Parse the contents
@@ -118,7 +118,7 @@ bool AnimationResource::parserCallback_animation(ParserNode *node) {
// Loop type value
const char *loopTypeString = node->values["type"].c_str();
-
+
if (strcmp(loopTypeString, "oneshot") == 0) {
_animationType = Animation::AT_ONESHOT;
} else if (strcmp(loopTypeString, "loop") == 0) {
@@ -148,7 +148,7 @@ bool AnimationResource::parserCallback_frame(ParserNode *node) {
}
frame.fileName = _pPackage->getAbsolutePath(fileString);
if (frame.fileName.empty()) {
- error("Could not create absolute path for file specified in <frame> tag in \"%s\": \"%s\".",
+ error("Could not create absolute path for file specified in <frame> tag in \"%s\": \"%s\".",
getFileName().c_str(), fileString);
return false;
}
diff --git a/engines/sword25/gfx/fontresource.cpp b/engines/sword25/gfx/fontresource.cpp
index 7657abb5f2..0aeca7c180 100644
--- a/engines/sword25/gfx/fontresource.cpp
+++ b/engines/sword25/gfx/fontresource.cpp
@@ -85,7 +85,7 @@ bool FontResource::parserCallback_font(ParserNode *node) {
getFileName().c_str(), DEFAULT_GAPWIDTH);
_gapWidth = DEFAULT_GAPWIDTH;
}
-
+
// Get a reference to the package manager
assert(_pKernel);
PackageManager *pPackage = _pKernel->getPackage();
diff --git a/engines/sword25/gfx/graphicengine.cpp b/engines/sword25/gfx/graphicengine.cpp
index 6b1c2bc514..91133b9fd2 100644
--- a/engines/sword25/gfx/graphicengine.cpp
+++ b/engines/sword25/gfx/graphicengine.cpp
@@ -365,7 +365,7 @@ void GraphicEngine::updateLastFrameDuration() {
}
bool GraphicEngine::saveThumbnailScreenshot(const Common::String &filename) {
- // Note: In ScumMVM, rather than saivng the thumbnail to a file, we store it in memory
+ // Note: In ScumMVM, rather than saivng the thumbnail to a file, we store it in memory
// until needed when creating savegame files
delete _thumbnail;
diff --git a/engines/sword25/gfx/image/art.cpp b/engines/sword25/gfx/image/art.cpp
index cd7cfb6b69..e9715481c6 100644
--- a/engines/sword25/gfx/image/art.cpp
+++ b/engines/sword25/gfx/image/art.cpp
@@ -151,6 +151,8 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) {
n_segs_max = 16;
svp = (ArtSVP *)malloc(sizeof(ArtSVP) +
(n_segs_max - 1) * sizeof(ArtSVPSeg));
+ if (!svp)
+ error("[art_svp_from_vpath] Cannot allocate memory");
dir = 0;
n_points = 0;
@@ -167,9 +169,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) {
if (points != NULL && n_points >= 2) {
if (n_segs == n_segs_max) {
n_segs_max <<= 1;
- svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
- (n_segs_max - 1) *
- sizeof(ArtSVPSeg));
+ ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
+ (n_segs_max - 1) *
+ sizeof(ArtSVPSeg));
+
+ if (!tmp)
+ error("Cannot reallocate memory in art_svp_from_vpath()");
+
+ svp = tmp;
}
svp->segs[n_segs].n_points = n_points;
svp->segs[n_segs].dir = (dir > 0);
@@ -204,9 +211,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) {
y = points[n_points - 1].y;
if (n_segs == n_segs_max) {
n_segs_max <<= 1;
- svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
- (n_segs_max - 1) *
- sizeof(ArtSVPSeg));
+ ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
+ (n_segs_max - 1) *
+ sizeof(ArtSVPSeg));
+
+ if (!tmp)
+ error("Cannot reallocate memory in art_svp_from_vpath()");
+
+ svp = tmp;
}
svp->segs[n_segs].n_points = n_points;
svp->segs[n_segs].dir = (dir > 0);
@@ -246,9 +258,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) {
if (n_points >= 2) {
if (n_segs == n_segs_max) {
n_segs_max <<= 1;
- svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
- (n_segs_max - 1) *
- sizeof(ArtSVPSeg));
+ ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
+ (n_segs_max - 1) *
+ sizeof(ArtSVPSeg));
+
+ if (!tmp)
+ error("Cannot reallocate memory in art_svp_from_vpath()");
+
+ svp = tmp;
}
svp->segs[n_segs].n_points = n_points;
svp->segs[n_segs].dir = (dir > 0);
@@ -1026,6 +1043,8 @@ struct _ArtPriPoint {
static ArtPriQ *art_pri_new(void) {
ArtPriQ *result = art_new(ArtPriQ, 1);
+ if (!result)
+ error("[art_pri_new] Cannot allocate memory");
result->n_items = 0;
result->n_items_max = 16;
@@ -1157,8 +1176,13 @@ static int art_svp_writer_rewind_add_segment(ArtSvpWriter *self, int wind_left,
(swr->n_segs_max - 1) *
sizeof(ArtSVPSeg));
swr->svp = svp;
- swr->n_points_max = art_renew(swr->n_points_max, int,
- swr->n_segs_max);
+ int *tmp = art_renew(swr->n_points_max, int,
+ swr->n_segs_max);
+
+ if (!tmp)
+ error("Cannot reallocate memory in art_svp_writer_rewind_add_segment()");
+
+ swr->n_points_max = tmp;
}
seg = &svp->segs[seg_num];
seg->n_points = 1;
@@ -1169,6 +1193,9 @@ static int art_svp_writer_rewind_add_segment(ArtSvpWriter *self, int wind_left,
seg->bbox.x1 = x;
seg->bbox.y1 = y;
seg->points = art_new(ArtPoint, init_n_points_max);
+ if (!seg->points)
+ error("[art_svp_writer_rewind_add_segment] Cannot allocate memory");
+
seg->points[0].x = x;
seg->points[0].y = y;
return seg_num;
@@ -1213,6 +1240,8 @@ ArtSVP *art_svp_writer_rewind_reap(ArtSvpWriter *self) {
ArtSvpWriter *art_svp_writer_rewind_new(ArtWindRule rule) {
ArtSvpWriterRewind *result = art_new(ArtSvpWriterRewind, 1);
+ if (!result)
+ error("[art_svp_writer_rewind_new] Cannot allocate memory");
result->super.add_segment = art_svp_writer_rewind_add_segment;
result->super.add_point = art_svp_writer_rewind_add_point;
@@ -1222,6 +1251,9 @@ ArtSvpWriter *art_svp_writer_rewind_new(ArtWindRule rule) {
result->n_segs_max = 16;
result->svp = (ArtSVP *)malloc(sizeof(ArtSVP) +
(result->n_segs_max - 1) * sizeof(ArtSVPSeg));
+ if (!result->svp)
+ error("[art_svp_writer_rewind_new] Cannot allocate memory");
+
result->svp->n_segs = 0;
result->n_points_max = art_new(int, result->n_segs_max);
@@ -1392,6 +1424,9 @@ static void art_svp_intersect_push_pt(ArtIntersectCtx *ctx, ArtActiveSeg *seg,
seg->y1 = y;
pri_pt = art_new(ArtPriPoint, 1);
+ if (!pri_pt)
+ error("[art_svp_intersect_push_pt] Cannot allocate memory");
+
pri_pt->x = x;
pri_pt->y = y;
pri_pt->user_data = seg;
@@ -1855,6 +1890,8 @@ static void art_svp_intersect_horiz(ArtIntersectCtx *ctx, ArtActiveSeg *seg,
return;
hs = art_new(ArtActiveSeg, 1);
+ if (!hs)
+ error("[art_svp_intersect_horiz] Cannot allocate memory");
hs->flags = ART_ACTIVE_FLAGS_DEL | (seg->flags & ART_ACTIVE_FLAGS_OUT);
if (seg->flags & ART_ACTIVE_FLAGS_OUT) {
@@ -1997,6 +2034,8 @@ static void art_svp_intersect_add_seg(ArtIntersectCtx *ctx, const ArtSVPSeg *in_
ArtActiveSeg *last = NULL;
ArtActiveSeg *left, *right;
ArtPriPoint *pri_pt = art_new(ArtPriPoint, 1);
+ if (!pri_pt)
+ error("[art_svp_intersect_add_seg] Cannot allocate memory");
seg->flags = 0;
seg->in_seg = in_seg;
@@ -2166,6 +2205,9 @@ void art_svp_intersector(const ArtSVP *in, ArtSvpWriter *out) {
return;
ctx = art_new(ArtIntersectCtx, 1);
+ if (!ctx)
+ error("[art_svp_intersector] Cannot allocate memory");
+
ctx->in = in;
ctx->out = out;
pq = art_pri_new();
@@ -2178,6 +2220,9 @@ void art_svp_intersector(const ArtSVP *in, ArtSvpWriter *out) {
ctx->in_curs = 0;
first_point = art_new(ArtPriPoint, 1);
+ if (!first_point)
+ error("[art_svp_intersector] Cannot allocate memory");
+
first_point->x = in->segs[0].points[0].x;
first_point->y = in->segs[0].points[0].y;
first_point->user_data = NULL;
@@ -2319,6 +2364,8 @@ static void art_svp_render_delete_active(int *active_segs, int j, int n_active_s
ArtSVPRenderAAIter *art_svp_render_aa_iter(const ArtSVP *svp,
int x0, int y0, int x1, int y1) {
ArtSVPRenderAAIter *iter = art_new(ArtSVPRenderAAIter, 1);
+ if (!iter)
+ error("[art_svp_render_aa_iter] Cannot allocate memory");
iter->svp = svp;
iter->y = y0;
@@ -2499,7 +2546,7 @@ void art_svp_render_aa_iter_step(ArtSVPRenderAAIter *iter, int *p_start,
ADD_STEP(x, xdelta)
}
if (x < x1) {
- this_ =
+ this_ =
(int)(delta * (1 - 0.5 *
(x_max - ix_max) * (x_max - ix_max) *
rslope));
diff --git a/engines/sword25/gfx/image/art.h b/engines/sword25/gfx/image/art.h
index bfeb31cc30..8c9c97bc57 100644
--- a/engines/sword25/gfx/image/art.h
+++ b/engines/sword25/gfx/image/art.h
@@ -51,10 +51,13 @@ namespace Sword25 {
#define art_expand(p, type, max) \
do { \
if(max) {\
- p = art_renew(p, type, max <<= 1); \
+ type *tmp = art_renew(p, type, max <<= 1); \
+ if (!tmp) error("Cannot reallocate memory for art data"); \
+ p = tmp; \
} else { \
max = 1; \
p = art_new(type, 1); \
+ if (!p) error("Cannot allocate memory for art data"); \
} \
} while (0)
diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index a9c9de4f0c..f5f33d8e02 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -373,17 +373,23 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
default: // alpha blending
#if defined(SCUMM_LITTLE_ENDIAN)
- if (cb != 255)
+ if (cb == 0)
+ *out = 0;
+ else if (cb != 255)
*out += ((b - *out) * a * cb) >> 16;
else
*out += ((b - *out) * a) >> 8;
out++;
- if (cg != 255)
+ if (cg == 0)
+ *out = 0;
+ else if (cg != 255)
*out += ((g - *out) * a * cg) >> 16;
else
*out += ((g - *out) * a) >> 8;
out++;
- if (cr != 255)
+ if (cr == 0)
+ *out = 0;
+ else if (cr != 255)
*out += ((r - *out) * a * cr) >> 16;
else
*out += ((r - *out) * a) >> 8;
@@ -393,17 +399,23 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
#else
*out = 255;
out++;
- if (cr != 255)
+ if (cr == 0)
+ *out = 0;
+ else if (cr != 255)
*out += ((r - *out) * a * cr) >> 16;
else
*out += ((r - *out) * a) >> 8;
out++;
- if (cg != 255)
+ if (cg == 0)
+ *out = 0;
+ else if (cg != 255)
*out += ((g - *out) * a * cg) >> 16;
else
*out += ((g - *out) * a) >> 8;
out++;
- if (cb != 255)
+ if (cb == 0)
+ *out = 0;
+ else if (cb != 255)
*out += ((b - *out) * a * cb) >> 16;
else
*out += ((b - *out) * a) >> 8;
diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp
index 9235ec2fcf..b9ce5f7e00 100644
--- a/engines/sword25/gfx/image/vectorimage.cpp
+++ b/engines/sword25/gfx/image/vectorimage.cpp
@@ -321,6 +321,8 @@ ArtBpath *VectorImage::storeBez(ArtBpath *bez, int lineStyle, int fillStyle0, in
bez[*bezNodes].code = ART_END;
ArtBpath *bez1 = art_new(ArtBpath, *bezNodes + 1);
+ if (!bez1)
+ error("[VectorImage::storeBez] Cannot allocate memory");
for (int i = 0; i <= *bezNodes; i++)
bez1[i] = bez[i];
diff --git a/engines/sword25/gfx/image/vectorimagerenderer.cpp b/engines/sword25/gfx/image/vectorimagerenderer.cpp
index 97dad3346d..6d4dc213f2 100644
--- a/engines/sword25/gfx/image/vectorimagerenderer.cpp
+++ b/engines/sword25/gfx/image/vectorimagerenderer.cpp
@@ -270,6 +270,9 @@ ArtVpath *art_vpath_cat(ArtVpath *a, ArtVpath *b) {
len_a = art_vpath_len(a);
len_b = art_vpath_len(b);
dest = art_new(ArtVpath, len_a + len_b + 1);
+ if (!dest)
+ error("[art_vpath_cat] Cannot allocate memory");
+
p = dest;
for (int i = 0; i < len_a; i++)
@@ -299,6 +302,8 @@ ArtVpath *art_vpath_reverse(ArtVpath *a) {
len = art_vpath_len(a);
dest = art_new(ArtVpath, len + 1);
+ if (!dest)
+ error("[art_vpath_reverse] Cannot allocate memory");
for (i = 0; i < len; i++) {
it = a[len - i - 1];
@@ -371,6 +376,8 @@ void drawBez(ArtBpath *bez1, ArtBpath *bez2, byte *buffer, int width, int height
int size = art_vpath_len(vec);
ArtVpath *vect = art_new(ArtVpath, size + 1);
+ if (!vect)
+ error("[drawBez] Cannot allocate memory");
int k;
for (k = 0; k < size; k++) {
diff --git a/engines/sword25/gfx/screenshot.cpp b/engines/sword25/gfx/screenshot.cpp
index 4f9ba1d3c5..de7b62fba9 100644
--- a/engines/sword25/gfx/screenshot.cpp
+++ b/engines/sword25/gfx/screenshot.cpp
@@ -67,8 +67,8 @@ bool Screenshot::saveToFile(Graphics::Surface *data, Common::WriteStream *stream
Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data) {
// This method takes a screen image with a dimension of 800x600, and creates a screenshot with a dimension of 200x125.
- // First 50 pixels are cut off the top and bottom (the interface boards in the game). The remaining image of 800x500
- // will be on a 16th of its size, reduced by being handed out in 4x4 pixel blocks and the average of each block
+ // First 50 pixels are cut off the top and bottom (the interface boards in the game). The remaining image of 800x500
+ // will be on a 16th of its size, reduced by being handed out in 4x4 pixel blocks and the average of each block
// generates a pixel of the target image. Finally, the result as a PNG file is stored as a file.
// The source image must be 800x600.
@@ -84,7 +84,7 @@ Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data)
// Über das Zielbild iterieren und einen Pixel zur Zeit berechnen.
uint x, y;
x = y = 0;
-
+
for (byte *pDest = (byte *)thumbnail.pixels; pDest < ((byte *)thumbnail.pixels + thumbnail.pitch * thumbnail.h); ) {
// Get an average over a 4x4 pixel block in the source image
int alpha, red, green, blue;
diff --git a/engines/sword25/gfx/staticbitmap.cpp b/engines/sword25/gfx/staticbitmap.cpp
index 60ad94e20f..0ae07b36b5 100644
--- a/engines/sword25/gfx/staticbitmap.cpp
+++ b/engines/sword25/gfx/staticbitmap.cpp
@@ -170,7 +170,10 @@ bool StaticBitmap::unpersist(InputPersistenceBlock &reader) {
result &= Bitmap::unpersist(reader);
Common::String resourceFilename;
reader.readString(resourceFilename);
- result &= initBitmapResource(resourceFilename);
+ // We may not have saves, and we actually do not need to
+ // restore them. So do not even try to load them.
+ if (!resourceFilename.hasPrefix("/saves"))
+ result &= initBitmapResource(resourceFilename);
result &= RenderObject::unpersistChildren(reader);
diff --git a/engines/sword25/gfx/text.cpp b/engines/sword25/gfx/text.cpp
index 8e18d2936d..82bb7cdff7 100644
--- a/engines/sword25/gfx/text.cpp
+++ b/engines/sword25/gfx/text.cpp
@@ -61,7 +61,7 @@ Text::Text(InputPersistenceBlock &reader, RenderObjectPtr<RenderObject> parentPt
// Temporarily set fields prior to unpersisting actual values
_modulationColor(0xffffffff),
_autoWrap(false),
- _autoWrapThreshold(AUTO_WRAP_THRESHOLD_DEFAULT) {
+ _autoWrapThreshold(AUTO_WRAP_THRESHOLD_DEFAULT) {
// Unpersist the fields
_initSuccess = unpersist(reader);
diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp
index 17e9199b5c..c88360e031 100644
--- a/engines/sword25/kernel/persistenceservice.cpp
+++ b/engines/sword25/kernel/persistenceservice.cpp
@@ -199,7 +199,7 @@ Common::String PersistenceService::getSavegameDirectory() {
// Try and return the path using the savegame subfolder. But if doesn't exist, fall back on the data directory
if (childNode.exists())
return childNode.getPath();
-
+
return node.getPath();
}
diff --git a/engines/sword25/package/packagemanager.cpp b/engines/sword25/package/packagemanager.cpp
index 5c869203c6..5549f50c3c 100644
--- a/engines/sword25/package/packagemanager.cpp
+++ b/engines/sword25/package/packagemanager.cpp
@@ -157,7 +157,7 @@ byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr)
byte *buffer = new byte[file->size()];
file->read(buffer, file->size());
-
+
delete file;
return buffer;
}
diff --git a/engines/sword25/package/packagemanager.h b/engines/sword25/package/packagemanager.h
index 3c4c4e89c5..b0c6718008 100644
--- a/engines/sword25/package/packagemanager.h
+++ b/engines/sword25/package/packagemanager.h
@@ -141,6 +141,9 @@ public:
uint fileSize;
char *data = (char *)getFile(fileName, &fileSize);
char *result = (char *)malloc(fileSize + strlen(versionStr) + 1);
+ if (!result)
+ error("[PackageManager::getXmlFile] Cannot allocate memory");
+
strcpy(result, versionStr);
Common::copy(data, data + fileSize, result + strlen(versionStr));
result[fileSize + strlen(versionStr)] = '\0';
@@ -151,7 +154,7 @@ public:
return result;
}
-
+
/**
* Returns the path to the current directory.
* @return Returns a string containing the path to the current directory.
diff --git a/engines/sword25/sfx/soundengine.cpp b/engines/sword25/sfx/soundengine.cpp
index 20622b2098..7c8a6593aa 100644
--- a/engines/sword25/sfx/soundengine.cpp
+++ b/engines/sword25/sfx/soundengine.cpp
@@ -37,6 +37,7 @@
#include "audio/decoders/vorbis.h"
#include "common/system.h"
+#include "common/config-manager.h"
namespace Sword25 {
@@ -60,13 +61,13 @@ SoundEngine::SoundEngine(Kernel *pKernel) : ResourceService(pKernel) {
_mixer = g_system->getMixer();
+ _maxHandleId = 1;
+
for (int i = 0; i < SOUND_HANDLES; i++)
_handles[i].type = kFreeHandle;
}
bool SoundEngine::init(uint sampleRate, uint channels) {
- warning("STUB: SoundEngine::init(%d, %d)", sampleRate, channels);
-
return true;
}
@@ -74,12 +75,44 @@ void SoundEngine::update() {
}
void SoundEngine::setVolume(float volume, SOUND_TYPES type) {
- warning("STUB: SoundEngine::setVolume(%f, %d)", volume, type);
+ int val = (int)(255 * volume);
+
+ switch (type) {
+ case SoundEngine::MUSIC:
+ ConfMan.setInt("music_volume", val);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, val);
+ break;
+ case SoundEngine::SPEECH:
+ ConfMan.setInt("speech_volume", val);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, val);
+ break;
+ case SoundEngine::SFX:
+ ConfMan.setInt("sfx_volume", val);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, val);
+ break;
+ default:
+ error("Unknown SOUND_TYPE");
+ }
}
float SoundEngine::getVolume(SOUND_TYPES type) {
- warning("STUB: SoundEngine::getVolume(%d)", type);
- return 0;
+ int val = 0;
+
+ switch (type) {
+ case SoundEngine::MUSIC:
+ val = ConfMan.getInt("music_volume");
+ break;
+ case SoundEngine::SPEECH:
+ val = ConfMan.getInt("speech_volume");
+ break;
+ case SoundEngine::SFX:
+ val = ConfMan.getInt("sfx_volume");
+ break;
+ default:
+ error("Unknown SOUND_TYPE");
+ }
+
+ return (float)val / 255.0;
}
void SoundEngine::pauseAll() {
@@ -95,28 +128,37 @@ void SoundEngine::resumeAll() {
}
void SoundEngine::pauseLayer(uint layer) {
- warning("STUB: SoundEngine::pauseLayer(%d)", layer);
+ // Not used in the game
+
+ warning("SoundEngine::pauseLayer(%d)", layer);
}
void SoundEngine::resumeLayer(uint layer) {
- warning("STUB: SoundEngine::resumeLayer(%d)", layer);
+ // Not used in the game
+
+ warning("SoundEngine::resumeLayer(%d)", layer);
}
SndHandle *SoundEngine::getHandle(uint *id) {
- // NOTE: Index 0 means error. Thus we're not using it
- for (uint i = 1; i < SOUND_HANDLES; i++) {
+ for (uint i = 0; i < SOUND_HANDLES; i++) {
if (_handles[i].type != kFreeHandle && !_mixer->isSoundHandleActive(_handles[i].handle)) {
- debugC(kDebugSound, 5, "Handle %d has finished playing", i);
+ debugC(1, kDebugSound, "Handle %d has finished playing", _handles[i].id);
_handles[i].type = kFreeHandle;
}
}
- for (uint i = 1; i < SOUND_HANDLES; i++) {
+ for (uint i = 0; i < SOUND_HANDLES; i++) {
if (_handles[i].type == kFreeHandle) {
- debugC(kDebugSound, 5, "Allocated handle %d", i);
+ debugC(1, kDebugSound, "Allocated handle %d", _handles[i].id);
+ _handles[i].id = _maxHandleId;
+ _handles[i].type = kAllocatedHandle;
+
if (id)
- *id = i;
+ *id = _maxHandleId;
+
+ _maxHandleId++;
+
return &_handles[i];
}
}
@@ -126,6 +168,17 @@ SndHandle *SoundEngine::getHandle(uint *id) {
return NULL;
}
+SndHandle *SoundEngine::findHandle(uint id) {
+ for (uint i = 0; i < SOUND_HANDLES; i++) {
+ if (_handles[i].id == id)
+ return &_handles[i];
+ }
+
+ warning("Sound::findHandle(): Unknown handle");
+
+ return NULL;
+}
+
Audio::Mixer::SoundType getType(SoundEngine::SOUND_TYPES type) {
switch (type) {
case SoundEngine::MUSIC:
@@ -159,6 +212,8 @@ uint SoundEngine::playSoundEx(const Common::String &fileName, SOUND_TYPES type,
debugC(1, kDebugSound, "SoundEngine::playSoundEx(%s, %d, %f, %f, %d, %d, %d, %d)", fileName.c_str(), type, volume, pan, loop, loopStart, loopEnd, layer);
+ handle->type = kAllocatedHandle;
+
#ifdef USE_VORBIS
_mixer->playStream(getType(type), &(handle->handle), stream, -1, (byte)(volume * 255), (int8)(pan * 127));
#endif
@@ -167,74 +222,81 @@ uint SoundEngine::playSoundEx(const Common::String &fileName, SOUND_TYPES type,
}
void SoundEngine::setSoundVolume(uint handle, float volume) {
- assert(handle < SOUND_HANDLES);
-
debugC(1, kDebugSound, "SoundEngine::setSoundVolume(%d, %f)", handle, volume);
- _mixer->setChannelVolume(_handles[handle].handle, (byte)(volume * 255));
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle != NULL)
+ _mixer->setChannelVolume(sndHandle->handle, (byte)(volume * 255));
}
void SoundEngine::setSoundPanning(uint handle, float pan) {
- assert(handle < SOUND_HANDLES);
-
debugC(1, kDebugSound, "SoundEngine::setSoundPanning(%d, %f)", handle, pan);
- _mixer->setChannelBalance(_handles[handle].handle, (int8)(pan * 127));
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle != NULL)
+ _mixer->setChannelBalance(sndHandle->handle, (int8)(pan * 127));
}
void SoundEngine::pauseSound(uint handle) {
- assert(handle < SOUND_HANDLES);
-
debugC(1, kDebugSound, "SoundEngine::pauseSound(%d)", handle);
- _mixer->pauseHandle(_handles[handle].handle, true);
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle != NULL)
+ _mixer->pauseHandle(sndHandle->handle, true);
}
void SoundEngine::resumeSound(uint handle) {
- assert(handle < SOUND_HANDLES);
-
debugC(1, kDebugSound, "SoundEngine::resumeSound(%d)", handle);
- _mixer->pauseHandle(_handles[handle].handle, false);
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle != NULL)
+ _mixer->pauseHandle(sndHandle->handle, false);
}
void SoundEngine::stopSound(uint handle) {
- assert(handle < SOUND_HANDLES);
-
debugC(1, kDebugSound, "SoundEngine::stopSound(%d)", handle);
- _mixer->stopHandle(_handles[handle].handle);
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle != NULL)
+ _mixer->stopHandle(sndHandle->handle);
}
bool SoundEngine::isSoundPaused(uint handle) {
- warning("STUB: SoundEngine::isSoundPaused(%d)", handle);
+ // Not used in the game
+
+ warning("SoundEngine::isSoundPaused(%d)", handle);
return false;
}
bool SoundEngine::isSoundPlaying(uint handle) {
- assert(handle < SOUND_HANDLES);
-
debugC(1, kDebugSound, "SoundEngine::isSoundPlaying(%d)", handle);
- return _mixer->isSoundHandleActive(_handles[handle].handle);
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle == NULL)
+ return false;
+ return _mixer->isSoundHandleActive(sndHandle->handle);
}
float SoundEngine::getSoundVolume(uint handle) {
- warning("STUB: SoundEngine::getSoundVolume(%d)", handle);
+ debugC(1, kDebugSound, "SoundEngine::getSoundVolume(%d)", handle);
- return 0;
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle == NULL)
+ return 0.f;
+ return (float)_mixer->getChannelVolume(sndHandle->handle) / 255.0;
}
float SoundEngine::getSoundPanning(uint handle) {
- warning("STUB: SoundEngine::getSoundPanning(%d)", handle);
+ debugC(1, kDebugSound, "SoundEngine::getSoundPanning(%d)", handle);
- return 0;
+ SndHandle* sndHandle = findHandle(handle);
+ if (sndHandle == NULL)
+ return 0.f;
+ return (float)_mixer->getChannelBalance(sndHandle->handle) / 127.0;
}
Resource *SoundEngine::loadResource(const Common::String &fileName) {
- warning("STUB: SoundEngine::loadResource(%s)", fileName.c_str());
-
return new SoundResource(fileName);
}
diff --git a/engines/sword25/sfx/soundengine.h b/engines/sword25/sfx/soundengine.h
index 4dbd475846..71f1602484 100644
--- a/engines/sword25/sfx/soundengine.h
+++ b/engines/sword25/sfx/soundengine.h
@@ -58,13 +58,13 @@ namespace Sword25 {
enum sndHandleType {
kFreeHandle,
- kEffectHandle,
- kVoiceHandle
+ kAllocatedHandle
};
struct SndHandle {
Audio::SoundHandle handle;
sndHandleType type;
+ uint32 id;
};
@@ -244,10 +244,13 @@ public:
private:
bool registerScriptBindings();
SndHandle *getHandle(uint *id);
+ SndHandle *findHandle(uint id);
private:
Audio::Mixer *_mixer;
SndHandle _handles[SOUND_HANDLES];
+
+ uint32 _maxHandleId;
};
} // End of namespace Sword25
diff --git a/engines/sword25/util/lua/lapi.cpp b/engines/sword25/util/lua/lapi.cpp
index 16f8460e39..ff25cfc653 100644
--- a/engines/sword25/util/lua/lapi.cpp
+++ b/engines/sword25/util/lua/lapi.cpp
@@ -213,7 +213,7 @@ LUA_API void lua_replace (lua_State *L, int idx) {
api_checkvalidindex(L, o);
if (idx == LUA_ENVIRONINDEX) {
Closure *func = curr_func(L);
- api_check(L, ttistable(L->top - 1));
+ api_check(L, ttistable(L->top - 1));
func->c.env = hvalue(L->top - 1);
luaC_barrier(L, func, L->top - 1);
}
@@ -773,7 +773,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
#define checkresults(L,na,nr) \
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
-
+
LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
StkId func;
diff --git a/engines/sword25/util/lua/lauxlib.cpp b/engines/sword25/util/lua/lauxlib.cpp
index 8978cd5613..1261777315 100644
--- a/engines/sword25/util/lua/lauxlib.cpp
+++ b/engines/sword25/util/lua/lauxlib.cpp
@@ -570,13 +570,13 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
}
c = lf.f->getc();
- if (c == '#') { // Unix exec. file?
+ if (c == '#') { // Unix exec. file?
lf.extraline = 1;
- while ((c = lf.f->getc()) != EOF && c != '\n') ; // skip first line
+ while ((c = lf.f->getc()) != EOF && c != '\n') ; // skip first line
if (c == '\n') c = lf.f->getc();
}
- if (c == LUA_SIGNATURE[0] && filename) { // binary file?
- lf.f = freopen(filename, "rb", lf.f); // reopen in binary mode
+ if (c == LUA_SIGNATURE[0] && filename) { // binary file?
+ lf.f = freopen(filename, "rb", lf.f); // reopen in binary mode
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
// skip eventual `#!...'
while ((c = lf.f->getc()) != EOF && c != LUA_SIGNATURE[0]) ;
diff --git a/engines/sword25/util/lua/ldblib.cpp b/engines/sword25/util/lua/ldblib.cpp
index 4d0333b46e..618e9a843f 100644
--- a/engines/sword25/util/lua/ldblib.cpp
+++ b/engines/sword25/util/lua/ldblib.cpp
@@ -142,7 +142,7 @@ static int db_getinfo (lua_State *L) {
treatstackoption(L, L1, "func");
return 1; /* return table */
}
-
+
static int db_getlocal (lua_State *L) {
int arg;
diff --git a/engines/sword25/util/lua/ldebug.cpp b/engines/sword25/util/lua/ldebug.cpp
index 0b26522b31..85c492cc77 100644
--- a/engines/sword25/util/lua/ldebug.cpp
+++ b/engines/sword25/util/lua/ldebug.cpp
@@ -184,7 +184,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
int i;
for (i=0; i<f->l.p->sizelineinfo; i++)
setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
- sethvalue(L, L->top, t);
+ sethvalue(L, L->top, t);
}
incr_top(L);
}
diff --git a/engines/sword25/util/lua/ldo.cpp b/engines/sword25/util/lua/ldo.cpp
index bbcdf98b3d..49e0881a45 100644
--- a/engines/sword25/util/lua/ldo.cpp
+++ b/engines/sword25/util/lua/ldo.cpp
@@ -384,7 +384,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
-*/
+*/
void luaD_call (lua_State *L, StkId func, int nResults) {
if (++L->nCcalls >= LUAI_MAXCCALLS) {
if (L->nCcalls == LUAI_MAXCCALLS)
diff --git a/engines/sword25/util/lua/lgc.cpp b/engines/sword25/util/lua/lgc.cpp
index 52ff72bdc9..71e581ad30 100644
--- a/engines/sword25/util/lua/lgc.cpp
+++ b/engines/sword25/util/lua/lgc.cpp
@@ -310,7 +310,7 @@ static l_mem propagatemark (global_State *g) {
traverseproto(g, p);
return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
sizeof(Proto *) * p->sizep +
- sizeof(TValue) * p->sizek +
+ sizeof(TValue) * p->sizek +
sizeof(int) * p->sizelineinfo +
sizeof(LocVar) * p->sizelocvars +
sizeof(TString *) * p->sizeupvalues;
@@ -697,7 +697,7 @@ void luaC_linkupval (lua_State *L, UpVal *uv) {
GCObject *o = obj2gco(uv);
o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
g->rootgc = o;
- if (isgray(o)) {
+ if (isgray(o)) {
if (g->gcstate == GCSpropagate) {
gray2black(o); /* closed upvalues need barrier */
luaC_barrier(L, uv, uv->v);
diff --git a/engines/sword25/util/lua/liolib.cpp b/engines/sword25/util/lua/liolib.cpp
index b505d1e4df..6c00de5094 100644
--- a/engines/sword25/util/lua/liolib.cpp
+++ b/engines/sword25/util/lua/liolib.cpp
@@ -228,7 +228,7 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
- // return current value
+ // return current value
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}
@@ -315,7 +315,7 @@ static int read_line (lua_State *L, Sword25::Sword25FileProxy *f) {
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
- if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { // eof?
+ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { // eof?
luaL_pushresult(&b); // close buffer
return (lua_objlen(L, -1) > 0); // check whether read something
}
@@ -332,19 +332,19 @@ static int read_line (lua_State *L, Sword25::Sword25FileProxy *f) {
static int read_chars (lua_State *L, Sword25::Sword25FileProxy *f, size_t n) {
- size_t rlen; // how much to read
- size_t nr; // number of chars actually read
+ size_t rlen; // how much to read
+ size_t nr; // number of chars actually read
luaL_Buffer b;
luaL_buffinit(L, &b);
- rlen = LUAL_BUFFERSIZE; // try to read that much each time
+ rlen = LUAL_BUFFERSIZE; // try to read that much each time
do {
char *p = luaL_prepbuffer(&b);
- if (rlen > n) rlen = n; // cannot read more than asked
+ if (rlen > n) rlen = n; // cannot read more than asked
nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr);
- n -= nr; // still have to read `n' chars
- } while (n > 0 && nr == rlen); // until end of count or eof
- luaL_pushresult(&b); // close buffer
+ n -= nr; // still have to read `n' chars
+ } while (n > 0 && nr == rlen); // until end of count or eof
+ luaL_pushresult(&b); // close buffer
return (n == 0 || lua_objlen(L, -1) > 0);
}
@@ -354,11 +354,11 @@ static int g_read (lua_State *L, Sword25::Sword25FileProxy *f, int first) {
int success;
int n;
clearerr(f);
- if (nargs == 0) { // no arguments?
+ if (nargs == 0) { // no arguments?
success = read_line(L, f);
- n = first+1; // to return 1 result
+ n = first+1; // to return 1 result
}
- else { // ensure stack space for all results and for auxlib's buffer
+ else { // ensure stack space for all results and for auxlib's buffer
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
@@ -370,15 +370,15 @@ static int g_read (lua_State *L, Sword25::Sword25FileProxy *f, int first) {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
- case 'n': // number
+ case 'n': // number
success = read_number(L, f);
break;
- case 'l': // line
+ case 'l': // line
success = read_line(L, f);
break;
- case 'a': // file
- read_chars(L, f, ~((size_t)0)); // read MAX_SIZE_T chars
- success = 1; // always success
+ case 'a': // file
+ read_chars(L, f, ~((size_t)0)); // read MAX_SIZE_T chars
+ success = 1; // always success
break;
default:
return luaL_argerror(L, n, "invalid format");
@@ -389,8 +389,8 @@ static int g_read (lua_State *L, Sword25::Sword25FileProxy *f, int first) {
if (ferror(f))
return pushresult(L, 0, NULL);
if (!success) {
- lua_pop(L, 1); // remove last result
- lua_pushnil(L); // push nil instead
+ lua_pop(L, 1); // remove last result
+ lua_pushnil(L); // push nil instead
}
return n - first;
}
@@ -419,8 +419,8 @@ static int io_readline (lua_State *L) {
if (ferror(f))
return luaL_error(L, "%s", "LUA I/O error descriptions have been removed in ScummVM");
if (sucess) return 1;
- else { // EOF
- if (lua_toboolean(L, lua_upvalueindex(2))) { // generator created file?
+ else { // EOF
+ if (lua_toboolean(L, lua_upvalueindex(2))) { // generator created file?
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); // close it
diff --git a/engines/sword25/util/lua/llex.cpp b/engines/sword25/util/lua/llex.cpp
index 4d73a6a600..b456ee2dfe 100644
--- a/engines/sword25/util/lua/llex.cpp
+++ b/engines/sword25/util/lua/llex.cpp
@@ -188,7 +188,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) {
sprintf(buf, "%.1f", 1.0);
ls->decpoint = '.';
for (i = 0; buf[i]; i++) {
- if (!isspace(buf[i]) && !isdigit(buf[i])) {
+ if (!isspace(static_cast<unsigned char>(buf[i])) && !isdigit(static_cast<unsigned char>(buf[i]))) {
ls->decpoint = buf[i];
break;
}
diff --git a/engines/sword25/util/lua/llimits.h b/engines/sword25/util/lua/llimits.h
index a31ad160ad..0925231350 100644
--- a/engines/sword25/util/lua/llimits.h
+++ b/engines/sword25/util/lua/llimits.h
@@ -107,7 +107,7 @@ typedef lu_int32 Instruction;
#ifndef lua_lock
-#define lua_lock(L) ((void) 0)
+#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
@@ -118,7 +118,7 @@ typedef lu_int32 Instruction;
/*
** macro to control inclusion of some hard tests on stack reallocation
-*/
+*/
#ifndef HARDSTACKTESTS
#define condhardstacktests(x) ((void)0)
#else
diff --git a/engines/sword25/util/lua/loadlib.cpp b/engines/sword25/util/lua/loadlib.cpp
index 9795a575f5..f4cdd70a78 100644
--- a/engines/sword25/util/lua/loadlib.cpp
+++ b/engines/sword25/util/lua/loadlib.cpp
@@ -182,7 +182,7 @@ static int ll_require (lua_State *L) {
** 'module' function
** =======================================================
*/
-
+
static void setfenv (lua_State *L) {
lua_Debug ar;
@@ -298,7 +298,7 @@ LUALIB_API int luaopen_package (lua_State *L) {
lua_setfield(L, -2, "__gc");
/* create `package' table */
luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
-#if defined(LUA_COMPAT_LOADLIB)
+#if defined(LUA_COMPAT_LOADLIB)
lua_getfield(L, -1, "loadlib");
lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
#endif
diff --git a/engines/sword25/util/lua/lobject.h b/engines/sword25/util/lua/lobject.h
index 35aaed028a..5418a918b1 100644
--- a/engines/sword25/util/lua/lobject.h
+++ b/engines/sword25/util/lua/lobject.h
@@ -337,7 +337,7 @@ typedef struct Node {
typedef struct Table {
CommonHeader;
- lu_byte flags; /* 1<<p means tagmethod(p) is not present */
+ lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
TValue *array; /* array part */
diff --git a/engines/sword25/util/lua/lopcodes.h b/engines/sword25/util/lua/lopcodes.h
index e1aed0f637..2f850c4365 100644
--- a/engines/sword25/util/lua/lopcodes.h
+++ b/engines/sword25/util/lua/lopcodes.h
@@ -186,8 +186,8 @@ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
-OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
-OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
+OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
+OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
@@ -197,8 +197,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
-OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
- if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
+OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
+ if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
@@ -240,7 +240,7 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test
-*/
+*/
enum OpArgMask {
OpArgN, /* argument is not used */
diff --git a/engines/sword25/util/lua/lstate.cpp b/engines/sword25/util/lua/lstate.cpp
index 495d75c8a6..e542bcbacc 100644
--- a/engines/sword25/util/lua/lstate.cpp
+++ b/engines/sword25/util/lua/lstate.cpp
@@ -36,7 +36,7 @@ typedef struct LG {
lua_State l;
global_State g;
} LG;
-
+
static void stack_init (lua_State *L1, lua_State *L) {
diff --git a/engines/sword25/util/lua/lstrlib.cpp b/engines/sword25/util/lua/lstrlib.cpp
index e5501b9b49..2a1b8690e2 100644
--- a/engines/sword25/util/lua/lstrlib.cpp
+++ b/engines/sword25/util/lua/lstrlib.cpp
@@ -635,7 +635,7 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
lua_pushlstring(L, s, e - s); /* keep original text */
}
else if (!lua_isstring(L, -1))
- luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
+ luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
luaL_addvalue(b); /* add result to accumulator */
}
diff --git a/engines/sword25/util/lua/ltable.cpp b/engines/sword25/util/lua/ltable.cpp
index b2ec0e912a..45381fe673 100644
--- a/engines/sword25/util/lua/ltable.cpp
+++ b/engines/sword25/util/lua/ltable.cpp
@@ -48,7 +48,7 @@
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
-
+
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)
@@ -303,7 +303,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
- setnodevector(L, t, nhsize);
+ setnodevector(L, t, nhsize);
if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
@@ -392,11 +392,11 @@ static Node *getfreepos (Table *t) {
/*
-** inserts a new key into a hash table; first, check whether key's main
-** position is free. If not, check whether colliding node is in its main
-** position or not: if it is not, move colliding node to an empty place and
-** put new key in its main position; otherwise (colliding node is in its main
-** position), new key goes to an empty position.
+** inserts a new key into a hash table; first, check whether key's main
+** position is free. If not, check whether colliding node is in its main
+** position or not: if it is not, move colliding node to an empty place and
+** put new key in its main position; otherwise (colliding node is in its main
+** position), new key goes to an empty position.
*/
static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp = mainposition(t, key);
diff --git a/engines/sword25/util/lua/lua.h b/engines/sword25/util/lua/lua.h
index 417cdadf8b..08ad80d70f 100644
--- a/engines/sword25/util/lua/lua.h
+++ b/engines/sword25/util/lua/lua.h
@@ -247,7 +247,7 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
-/*
+/*
** ===============================================================
** some useful macros
** ===============================================================
diff --git a/engines/sword25/util/lua/lualib.h b/engines/sword25/util/lua/lualib.h
index 33d4e314c2..830f6a0894 100644
--- a/engines/sword25/util/lua/lualib.h
+++ b/engines/sword25/util/lua/lualib.h
@@ -41,7 +41,7 @@ LUALIB_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */
-LUALIB_API void (luaL_openlibs) (lua_State *L);
+LUALIB_API void (luaL_openlibs) (lua_State *L);
diff --git a/engines/sword25/util/lua/lvm.cpp b/engines/sword25/util/lua/lvm.cpp
index fb700c20a2..d0f2198651 100644
--- a/engines/sword25/util/lua/lvm.cpp
+++ b/engines/sword25/util/lua/lvm.cpp
@@ -125,7 +125,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
callTMres(L, val, tm, t, key);
return;
}
- t = tm; /* else repeat with `tm' */
+ t = tm; /* else repeat with `tm' */
}
luaG_runerror(L, "loop in gettable");
}
@@ -152,7 +152,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
callTM(L, tm, t, key, val);
return;
}
- t = tm; /* else repeat with `tm' */
+ t = tm; /* else repeat with `tm' */
}
luaG_runerror(L, "loop in settable");
}
diff --git a/engines/sword25/util/lua/scummvm_file.cpp b/engines/sword25/util/lua/scummvm_file.cpp
index 3c0377d0ee..33053a71cb 100644
--- a/engines/sword25/util/lua/scummvm_file.cpp
+++ b/engines/sword25/util/lua/scummvm_file.cpp
@@ -32,11 +32,30 @@ Sword25FileProxy::Sword25FileProxy(const Common::String &filename, const Common:
setupConfigFile();
}
+Common::String Sword25FileProxy::formatDouble(double value) {
+ // This is a bit hackish. The point of it is that it's important that
+ // we ignore the locale decimal mark and force it to be a point. If it
+ // would happen to be a comma instead, it seems that it's seen as two
+ // comma-separated integers rather than one floating-point value. Or
+ // something like that.
+
+ bool negative = value < 0.0;
+ value = fabs(value);
+ double integerPart = floor(value);
+ double fractionalPart = (value - integerPart) * 1000000.0;
+
+ Common::String out = Common::String::format("%.0f.%.0f", integerPart, fractionalPart);
+ if (negative)
+ out = "-" + out;
+
+ return out;
+}
+
void Sword25FileProxy::setupConfigFile() {
- double sfxVolume = ConfMan.hasKey("sfx_volume") ? 1.0 : 1.0 * ConfMan.getInt("sfx_volume") / 255.0;
- double musicVolume = ConfMan.hasKey("music_volume") ? 0.5 : 1.0 * ConfMan.getInt("music_volume") / 255.0;
- double speechVolume = ConfMan.hasKey("speech_volume") ? 1.0 : 1.0 * ConfMan.getInt("speech_volume") / 255.0;
- bool subtitles = ConfMan.hasKey("subtitles") ? true : ConfMan.getBool("subtitles");
+ double sfxVolume = !ConfMan.hasKey("sfx_volume") ? 1.0 : 1.0 * ConfMan.getInt("sfx_volume") / 255.0;
+ double musicVolume = !ConfMan.hasKey("music_volume") ? 0.5 : 1.0 * ConfMan.getInt("music_volume") / 255.0;
+ double speechVolume = !ConfMan.hasKey("speech_volume") ? 1.0 : 1.0 * ConfMan.getInt("speech_volume") / 255.0;
+ bool subtitles = !ConfMan.hasKey("subtitles") ? true : ConfMan.getBool("subtitles");
_readData = Common::String::format(
"GAME_LANGUAGE = \"%s\"\r\n\
@@ -45,10 +64,13 @@ MAX_MEMORY_USAGE = 256000000\r\n\
GFX_VSYNC_ACTIVE = true\r\n\
SFX_SAMPLING_RATE = 44100\r\n\
SFX_CHANNEL_COUNT = 32\r\n\
-SFX_SOUND_VOLUME = %f\r\n\
-SFX_MUSIC_VOLUME = %f\r\n\
-SFX_SPEECH_VOLUME = %f\r\n",
- getLanguage().c_str(), subtitles ? "true" : "false", sfxVolume, musicVolume, speechVolume);
+SFX_SOUND_VOLUME = %s\r\n\
+SFX_MUSIC_VOLUME = %s\r\n\
+SFX_SPEECH_VOLUME = %s\r\n",
+ getLanguage().c_str(), subtitles ? "true" : "false",
+ formatDouble(sfxVolume).c_str(),
+ formatDouble(musicVolume).c_str(),
+ formatDouble(speechVolume).c_str());
_readPos = 0;
}
@@ -76,14 +98,14 @@ size_t Sword25FileProxy::write(const char *ptr, size_t count) {
// Legitimate data
const char *p = strchr(ptr, '\n');
if (!p) p = ptr + strlen(ptr);
- while ((*p == '\r') || (*p == '\n'))
+ while ((*p == '\r') || (*p == '\n'))
++p;
_settings += Common::String(ptr, p - ptr);
ptr = p;
}
- while ((*ptr == '\r') || (*ptr == '\n'))
+ while ((*ptr == '\r') || (*ptr == '\n'))
++ptr;
}
@@ -97,7 +119,7 @@ void Sword25FileProxy::writeSettings() {
if ((*pSrc != '\r') && (*pSrc != '\n')) {
const char *p = strchr(pSrc, '=');
assert(p);
-
+
// Get the setting name
const char *pEnd = p - 1;
while (*pEnd == ' ')
@@ -110,10 +132,10 @@ void Sword25FileProxy::writeSettings() {
++pStart;
pEnd = pStart + 1;
- while ((*pEnd != '\r') && (*pEnd != '\n') && (*pEnd != '\0'))
+ while ((*pEnd != '\r') && (*pEnd != '\n') && (*pEnd != '\0'))
++pEnd;
Common::String value(pStart + (*pStart == '"' ? 1 : 0), pEnd - pStart - (*pStart == '"' ? 2 : 0));
-
+
// Update the setting
updateSetting(settingName, value);
pSrc = pEnd;
diff --git a/engines/sword25/util/lua/scummvm_file.h b/engines/sword25/util/lua/scummvm_file.h
index a4cbd2a6cf..e8c468ee07 100644
--- a/engines/sword25/util/lua/scummvm_file.h
+++ b/engines/sword25/util/lua/scummvm_file.h
@@ -37,6 +37,7 @@ private:
uint _readPos;
Common::String _settings;
+ Common::String formatDouble(double value);
void setupConfigFile();
Common::String getLanguage();
void setLanguage(const Common::String &lang);
diff --git a/engines/teenagent/animation.cpp b/engines/teenagent/animation.cpp
index af54bca6a4..e945bda1e5 100644
--- a/engines/teenagent/animation.cpp
+++ b/engines/teenagent/animation.cpp
@@ -115,7 +115,7 @@ void Animation::load(Common::SeekableReadStream *s, Type type) {
return;
}
- uint16 pos = 0;
+ //uint16 pos = 0;
int off = 0;
switch (type) {
case kTypeLan:
@@ -141,7 +141,7 @@ void Animation::load(Common::SeekableReadStream *s, Type type) {
frames = new Surface[frames_count];
s->skip(frames_count * 2 - 2); //sizes
- pos = s->readUint16LE();
+ /*pos = */s->readUint16LE();
//debug(0, "pos?: %04x", pos);
for (uint16 i = 0; i < frames_count; ++i) {
diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp
index 5012e6af65..72a338664b 100644
--- a/engines/teenagent/detection.cpp
+++ b/engines/teenagent/detection.cpp
@@ -79,37 +79,14 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
AD_TABLE_END_MARKER,
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)teenAgentGameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- teenAgentGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "teenagent",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
+enum {
+ MAX_SAVES = 20
};
-#define MAX_SAVES 20
-
-
class TeenAgentMetaEngine : public AdvancedMetaEngine {
public:
- TeenAgentMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TeenAgentMetaEngine() : AdvancedMetaEngine(teenAgentGameDescriptions, sizeof(ADGameDescription), teenAgentGames) {
+ _singleid = "teenagent";
}
virtual const char *getName() const {
@@ -140,10 +117,6 @@ public:
return desc != 0;
}
-// virtual const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const {
-// return 0;
-// }
-
static Common::String generateGameStateFileName(const char *target, int slot) {
return Common::String::format("%s.%02d", target, slot);
}
diff --git a/engines/teenagent/inventory.cpp b/engines/teenagent/inventory.cpp
index 8430f42c61..4951b2d940 100644
--- a/engines/teenagent/inventory.cpp
+++ b/engines/teenagent/inventory.cpp
@@ -58,7 +58,7 @@ Inventory::Inventory(TeenAgentEngine *engine) {
for (byte i = 0; i < offsets; ++i) {
_offset[i] = READ_LE_UINT16(_items + i * 2 + 1);
}
- _offset[92] = items_size;
+ _offset[92] = items_size;
Resources *res = Resources::instance();
for (byte i = 0; i <= 92; ++i) {
diff --git a/engines/teenagent/inventory.h b/engines/teenagent/inventory.h
index 55c58a1c22..61e5364542 100644
--- a/engines/teenagent/inventory.h
+++ b/engines/teenagent/inventory.h
@@ -75,12 +75,12 @@ private:
void backgroundEffect(Graphics::Surface *s);
void render(Inventory *inventory, uint item_id, Graphics::Surface *surface, int delta);
};
-
+
Item _graphics[24];
bool _active;
Common::Point _mouse;
-
+
bool tryObjectCallback(InventoryObject *obj);
InventoryObject *_hoveredObj;
diff --git a/engines/teenagent/resources.cpp b/engines/teenagent/resources.cpp
index 9e69383215..597ca670c0 100644
--- a/engines/teenagent/resources.cpp
+++ b/engines/teenagent/resources.cpp
@@ -106,13 +106,20 @@ void Resources::loadOff(Graphics::Surface &surface, byte *palette, int id) {
error("invalid background %d", id);
return;
}
- byte buf[64768];
- off.read(id, buf, sizeof(buf));
+
+ const uint bufferSize = 64768;
+ byte *buf = (byte *)malloc(bufferSize);
+ if (!buf)
+ error("[Resources::loadOff] Cannot allocate buffer");
+
+ off.read(id, buf, bufferSize);
byte *src = buf;
byte *dst = (byte *)surface.pixels;
memcpy(dst, src, 64000);
memcpy(palette, buf + 64000, 768);
+
+ free(buf);
}
Common::SeekableReadStream *Resources::loadLan(uint32 id) const {
diff --git a/engines/teenagent/resources.h b/engines/teenagent/resources.h
index c2eb32dbd4..5c08a46489 100644
--- a/engines/teenagent/resources.h
+++ b/engines/teenagent/resources.h
@@ -44,9 +44,9 @@ public:
//void loadOn(Graphics::Surface &surface, int id, uint16 &dst, uint16 *flags);
//void loadOns(Graphics::Surface &surface, int id, uint16 &dst);
- /*
- * PSP (as the other sony playstation consoles - to be confirmed and 'ifdef'ed here too)
- * is very sensitive to the number of simultaneously opened files.
+ /*
+ * PSP (as the other sony playstation consoles - to be confirmed and 'ifdef'ed here too)
+ * is very sensitive to the number of simultaneously opened files.
* This is an attempt to reduce their number to zero.
* TransientFilePack does not keep opened file descriptors and reopens it on each request.
*/
diff --git a/engines/teenagent/scene.cpp b/engines/teenagent/scene.cpp
index ef18b95f5a..4be6c9c31a 100644
--- a/engines/teenagent/scene.cpp
+++ b/engines/teenagent/scene.cpp
@@ -576,7 +576,7 @@ void Scene::paletteEffect(byte step) {
byte *src = res->dseg.ptr(0x6609);
byte *dst = palette + 3 * 0xf2;
for(byte i = 0; i < 0xd; ++i) {
- for(byte c = 0; c < 3; ++c, ++src)
+ for(byte c = 0; c < 3; ++c, ++src)
*dst++ = *src > step? *src - step: 0;
}
}
@@ -812,9 +812,9 @@ bool Scene::render(bool tick_game, bool tick_mark, uint32 delta) {
_system->unlockScreen();
continue;
}
- //removed mark == null. In final scene of chapter 2 mark rendered above table.
- //if it'd cause any bugs, add hack here. (_id != 23 && mark == NULL)
- if (on_enabled &&
+ //removed mark == null. In final scene of chapter 2 mark rendered above table.
+ //if it'd cause any bugs, add hack here. (_id != 23 && mark == NULL)
+ if (on_enabled &&
debug_features.feature[DebugFeatures::kShowOn]) {
on.render(surface, actor_animation_position);
}
diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp
index ce8862ffd0..0289b994e6 100644
--- a/engines/teenagent/teenagent.cpp
+++ b/engines/teenagent/teenagent.cpp
@@ -206,7 +206,7 @@ void TeenAgentEngine::deinit() {
Common::Error TeenAgentEngine::loadGameState(int slot) {
debug(0, "loading from slot %d", slot);
- Common::ScopedPtr<Common::InSaveFile>
+ Common::ScopedPtr<Common::InSaveFile>
in(_saveFileMan->openForLoading(Common::String::format("teenagent.%02d", slot)));
if (!in)
in.reset(_saveFileMan->openForLoading(Common::String::format("teenagent.%d", slot)));
@@ -216,14 +216,22 @@ Common::Error TeenAgentEngine::loadGameState(int slot) {
Resources *res = Resources::instance();
- assert(res->dseg.size() >= 0x6478 + 0x777a);
- char data[0x777a];
+ const uint dataSize = 0x777a;
+ assert(res->dseg.size() >= 0x6478 + dataSize);
+
+ char *data = (char *)malloc(dataSize);
+ if (!data)
+ error("[TeenAgentEngine::loadGameState] Cannot allocate buffer");
+
in->seek(0);
- if (in->read(data, 0x777a) != 0x777a) {
+ if (in->read(data, dataSize) != dataSize) {
+ free(data);
return Common::kReadingFailed;
}
- memcpy(res->dseg.ptr(0x6478), data, sizeof(data));
+ memcpy(res->dseg.ptr(0x6478), data, dataSize);
+
+ free(data);
scene->clear();
inventory->activate(false);
@@ -290,17 +298,32 @@ bool TeenAgentEngine::showCDLogo() {
if (!cdlogo.exists("cdlogo.res") || !cdlogo.open("cdlogo.res"))
return true;
- byte bg[0xfa00];
- byte palette[3*256];
+ const uint bgSize = 0xfa00;
+ const uint paletteSize = 3 * 256;
+
+ byte *bg = (byte *)malloc(bgSize);
+ if (!bg)
+ error("[TeenAgentEngine::showCDLogo] Cannot allocate background buffer");
- cdlogo.read(bg, sizeof(bg));
- cdlogo.read(palette, sizeof(palette));
- for (uint c = 0; c < 3*256; ++c)
+ byte *palette = (byte *)malloc(paletteSize);
+ if (!palette) {
+ free(bg);
+ error("[TeenAgentEngine::showCDLogo] Cannot allocate palette buffer");
+ }
+
+ cdlogo.read(bg, bgSize);
+ cdlogo.read(palette, paletteSize);
+
+ for (uint c = 0; c < paletteSize; ++c)
palette[c] *= 4;
+
_system->getPaletteManager()->setPalette(palette, 0, 0x100);
_system->copyRectToScreen(bg, 320, 0, 0, 320, 200);
_system->updateScreen();
+ free(bg);
+ free(palette);
+
for(uint i = 0; i < 20; ++i) {
int r = skipEvents();
if (r != 0)
@@ -317,43 +340,66 @@ bool TeenAgentEngine::showLogo() {
if (!logo.open("unlogic.res"))
return true;
- byte bg[0xfa00];
- byte palette[3*256];
-
Common::ScopedPtr<Common::SeekableReadStream> frame(logo.getStream(1));
if (!frame)
return true;
- frame->read(bg, sizeof(bg));
- frame->read(palette, sizeof(palette));
- for (uint c = 0; c < 3*256; ++c)
+ const uint bgSize = 0xfa00;
+ const uint paletteSize = 3 * 256;
+
+ byte *bg = (byte *)malloc(bgSize);
+ if (!bg)
+ error("[TeenAgentEngine::showLogo] Cannot allocate background buffer");
+
+ byte *palette = (byte *)malloc(paletteSize);
+ if (!palette) {
+ free(bg);
+ error("[TeenAgentEngine::showLogo] Cannot allocate palette buffer");
+ }
+
+ frame->read(bg, bgSize);
+ frame->read(palette, paletteSize);
+
+ for (uint c = 0; c < paletteSize; ++c)
palette[c] *= 4;
+
_system->getPaletteManager()->setPalette(palette, 0, 0x100);
+ free(palette);
+
uint n = logo.fileCount();
for(uint f = 0; f < 4; ++f)
for(uint i = 2; i <= n; ++i) {
{
int r = skipEvents();
- if (r != 0)
+ if (r != 0) {
+ free(bg);
return r > 0? true: false;
+ }
}
_system->copyRectToScreen(bg, 320, 0, 0, 320, 200);
frame.reset(logo.getStream(i));
- if (!frame)
+ if (!frame) {
+ free(bg);
return true;
+ }
Surface s;
s.load(frame, Surface::kTypeOns);
- if (s.empty())
+ if (s.empty()) {
+ free(bg);
return true;
+ }
_system->copyRectToScreen((const byte *)s.pixels, s.w, s.x, s.y, s.w, s.h);
_system->updateScreen();
_system->delayMillis(100);
}
+
+ free(bg);
+
return true;
}
@@ -364,29 +410,53 @@ bool TeenAgentEngine::showMetropolis() {
FilePack varia;
varia.open("varia.res");
- byte palette[3*256];
+ const uint paletteSize = 3 * 256;
+ byte *palette = (byte *)malloc(paletteSize);
+ if (!palette)
+ error("[TeenAgentEngine::showMetropolis] Cannot allocate palette buffer");
+
{
Common::ScopedPtr<Common::SeekableReadStream> s(varia.getStream(5));
- s->read(palette, sizeof(palette));
- for (uint c = 0; c < 3*256; ++c)
+ s->read(palette, paletteSize);
+ for (uint c = 0; c < paletteSize; ++c)
palette[c] *= 4;
}
_system->getPaletteManager()->setPalette(palette, 0, 0x100);
- byte varia_6[21760], varia_9[18302];
- varia.read(6, varia_6, sizeof(varia_6));
- varia.read(9, varia_9, sizeof(varia_9));
+ free(palette);
- byte colors[56 * 160 * 2];
- memset(colors, 0, sizeof(colors));
+ const uint varia6Size = 21760;
+ const uint varia9Size = 18302;
+ byte *varia_6 = (byte *)malloc(varia6Size);
+ byte *varia_9 = (byte *)malloc(varia9Size);
+ if (!varia_6 || !varia_9) {
+ free(varia_6);
+ free(varia_9);
+
+ error("[TeenAgentEngine::showMetropolis] Cannot allocate buffer");
+ }
+
+ varia.read(6, varia_6, varia6Size);
+ varia.read(9, varia_9, varia9Size);
+
+ const uint colorsSize = 56 * 160 * 2;
+ byte *colors = (byte *)malloc(colorsSize);
+ if (!colors)
+ error("[TeenAgentEngine::showMetropolis] Cannot allocate colors buffer");
+
+ memset(colors, 0, colorsSize);
int logo_y = -56;
for(uint f = 0; f < 300; ++f) {
{
int r = skipEvents();
- if (r != 0)
+ if (r != 0) {
+ free(varia_6);
+ free(varia_9);
+ free(colors);
return r > 0? true: false;
+ }
}
Graphics::Surface *surface = _system->lockScreen();
@@ -441,6 +511,11 @@ bool TeenAgentEngine::showMetropolis() {
_system->updateScreen();
_system->delayMillis(100);
}
+
+ free(varia_6);
+ free(varia_9);
+ free(colors);
+
return true;
}
@@ -963,10 +1038,10 @@ void TeenAgentEngine::playSoundNow(byte id) {
void TeenAgentEngine::setMusic(byte id) {
debug(0, "starting music %u", id);
Resources *res = Resources::instance();
-
+
if (id != 1) //intro music
*res->dseg.ptr(0xDB90) = id;
-
+
if (_gameDescription->flags & ADGF_CD) {
byte track2cd[] = {7, 2, 0, 9, 3, 6, 8, 10, 4, 5, 11};
if (id == 0 || id > 11 || track2cd[id - 1] == 0) {
diff --git a/engines/testbed/config-params.h b/engines/testbed/config-params.h
index e982f62c72..6906d9248e 100644
--- a/engines/testbed/config-params.h
+++ b/engines/testbed/config-params.h
@@ -34,7 +34,7 @@ class ConfigParams : public Common::Singleton<ConfigParams> {
private:
friend class Common::Singleton<SingletonBaseType>;
ConfigParams();
-
+
/**
* Private variables related to log files.
*/
@@ -57,16 +57,16 @@ private:
TestbedConfigManager *_testbedConfMan;
public:
-
+
bool isRerunRequired();
void setRerunFlag(bool flag) { _rerunTests = flag; }
bool isSessionInteractive() { return _isInteractive; }
void setSessionAsInteractive(bool status) { _isInteractive = status; }
-
+
bool isGameDataFound() { return _isGameDataFound; }
void setGameDataFound(bool status) { _isGameDataFound = status; }
-
+
TestbedConfigManager *getTestbedConfigManager() { return _testbedConfMan; }
void setTestbedConfigManager(TestbedConfigManager* confMan) { _testbedConfMan = confMan; }
@@ -74,7 +74,7 @@ public:
void setLogDirectory(const Common::String &dirname) { _logDirectory = dirname; }
Common::String &getLogFilename() { return _logFilename; }
void setLogFilename(const Common::String &filename) { _logFilename = filename; }
-
+
Common::WriteStream *getLogWriteStream() { return _ws; }
Graphics::FontManager::FontUsage getCurrentFontUsageType() { return _displayFont; }
void setCurrentFontUsageType(Graphics::FontManager::FontUsage f) { _displayFont = f; }
diff --git a/engines/testbed/config.cpp b/engines/testbed/config.cpp
index 6adf82952f..6bd4c82b41 100644
--- a/engines/testbed/config.cpp
+++ b/engines/testbed/config.cpp
@@ -126,10 +126,13 @@ void TestbedOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd,
ws = _testbedConfMan->getConfigWriteStream();
_testbedConfMan->writeTestbedConfigToStream(ws);
delete ws;
- default:
- GUI::Dialog::handleCommand(sender, cmd, data);
+ break;
+ default:
+ break;
}
+
+ GUI::Dialog::handleCommand(sender, cmd, data);
}
void TestbedInteractionDialog::addText(uint w, uint h, const Common::String text, Graphics::TextAlign textAlign, uint xOffset, uint yPadding) {
@@ -150,7 +153,7 @@ void TestbedInteractionDialog::addButton(uint w, uint h, const Common::String na
_yOffset += h;
}
-void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors, uint yPadding) {
+void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, const Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors, uint yPadding) {
_yOffset += yPadding;
GUI::ListWidget *list = new GUI::ListWidget(this, x, y, w, h);
list->setEditable(false);
@@ -159,7 +162,7 @@ void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, Common::A
_yOffset += h;
}
-void TestbedInteractionDialog::addButtonXY(uint x, uint y, uint w, uint h, const Common::String name, uint32 cmd) {
+void TestbedInteractionDialog::addButtonXY(uint x, uint /* y */, uint w, uint h, const Common::String name, uint32 cmd) {
_buttonArray.push_back(new GUI::ButtonWidget(this, x, _yOffset, w, h, name, 0, cmd));
}
@@ -174,7 +177,6 @@ void TestbedConfigManager::initDefaultConfiguration() {
}
void TestbedConfigManager::writeTestbedConfigToStream(Common::WriteStream *ws) {
- Common::String wStr;
for (Common::Array<Testsuite *>::const_iterator i = _testsuiteList.begin(); i < _testsuiteList.end(); i++) {
_configFileInterface.setKey("this", (*i)->getName(), boolToString((*i)->isEnabled()));
const Common::Array<Test *> &testList = (*i)->getTestList();
@@ -186,13 +188,13 @@ void TestbedConfigManager::writeTestbedConfigToStream(Common::WriteStream *ws) {
ws->flush();
}
-Common::SeekableReadStream *TestbedConfigManager::getConfigReadStream() {
+Common::SeekableReadStream *TestbedConfigManager::getConfigReadStream() const {
// Look for config file using SearchMan
Common::SeekableReadStream *rs = SearchMan.createReadStreamForMember(_configFileName);
return rs;
}
-Common::WriteStream *TestbedConfigManager::getConfigWriteStream() {
+Common::WriteStream *TestbedConfigManager::getConfigWriteStream() const {
// Look for config file in game-path
const Common::String &path = ConfMan.get("path");
Common::WriteStream *ws;
diff --git a/engines/testbed/config.h b/engines/testbed/config.h
index c0df65ad32..fd5588aa31 100644
--- a/engines/testbed/config.h
+++ b/engines/testbed/config.h
@@ -50,8 +50,8 @@ public:
~TestbedConfigManager() {}
void selectTestsuites();
void setConfigFile(const Common::String fName) { _configFileName = fName; }
- Common::SeekableReadStream *getConfigReadStream();
- Common::WriteStream *getConfigWriteStream();
+ Common::SeekableReadStream *getConfigReadStream() const;
+ Common::WriteStream *getConfigWriteStream() const;
void writeTestbedConfigToStream(Common::WriteStream *ws);
Testsuite *getTestsuiteByName(const Common::String &name);
bool stringToBool(const Common::String str) { return str.equalsIgnoreCase("true") ? true : false; }
@@ -119,7 +119,7 @@ public:
void addButton(uint w, uint h, const Common::String name, uint32 cmd, uint xOffset = 0, uint yPadding = 8);
void addButtonXY(uint x, uint y, uint w, uint h, const Common::String name, uint32 cmd);
void addText(uint w, uint h, const Common::String text, Graphics::TextAlign textAlign, uint xOffset, uint yPadding = 8);
- void addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors = 0, uint yPadding = 8);
+ void addList(uint x, uint y, uint w, uint h, const Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors = 0, uint yPadding = 8);
protected:
Common::Array<GUI::ButtonWidget *> _buttonArray;
uint _xOffset;
diff --git a/engines/testbed/detection.cpp b/engines/testbed/detection.cpp
index 91518b2b8e..b869bb8ebb 100644
--- a/engines/testbed/detection.cpp
+++ b/engines/testbed/detection.cpp
@@ -45,34 +45,11 @@ static const ADGameDescription testbedDescriptions[] = {
AD_TABLE_END_MARKER
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)testbedDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 512,
- // List of all engine targets
- testbed_setting,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "testbed",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- ADGF_NO_FLAGS,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class TestbedMetaEngine : public AdvancedMetaEngine {
public:
- TestbedMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TestbedMetaEngine() : AdvancedMetaEngine(testbedDescriptions, sizeof(ADGameDescription), testbed_setting) {
+ _md5Bytes = 512;
+ _singleid = "testbed";
}
virtual const char *getName() const {
@@ -83,7 +60,7 @@ public:
return "Copyright (C) ScummVM";
}
- virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription * /* desc */) const {
// Instantiate Engine even if the game data is not found.
*engine = new Testbed::TestbedEngine(syst);
return true;
diff --git a/engines/testbed/fs.cpp b/engines/testbed/fs.cpp
index e2bedb1898..62ac616192 100644
--- a/engines/testbed/fs.cpp
+++ b/engines/testbed/fs.cpp
@@ -167,7 +167,7 @@ TestExitStatus FStests::testWriteFile() {
return kTestPassed;
}
- return kTestFailed;
+ return kTestFailed;
}
@@ -189,7 +189,7 @@ FSTestSuite::FSTestSuite() {
}
void FSTestSuite::enable(bool flag) {
- Testsuite::enable(ConfParams.isGameDataFound() & flag);
+ Testsuite::enable(ConfParams.isGameDataFound() ? flag : false);
}
} // End of namespace Testbed
diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index d5b5da788a..36ec726fc7 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -102,7 +102,7 @@ void GFXtests::initMousePalette() {
CursorMan.replaceCursorPalette(palette, 0, 3);
}
-Common::Rect GFXtests::computeSize(Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale) {
+Common::Rect GFXtests::computeSize(const Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale) {
if (cursorTargetScale == 1 || scalingFactor == 1) {
// Game data and cursor would be scaled equally.
// so dimensions would be same.
@@ -137,7 +137,7 @@ void GFXtests::HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, in
float f, p, q, t;
if (s == 0) {
- r = g = b = v * 255;
+ rComp = gComp = bComp = (int)(v * 255);
return;
}
@@ -186,7 +186,7 @@ void GFXtests::HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, in
bComp = (int)(b * 255);
}
-Common::Rect GFXtests::drawCursor(bool cursorPaletteDisabled, const char *gfxModeName, int cursorTargetScale) {
+Common::Rect GFXtests::drawCursor(bool cursorPaletteDisabled, int cursorTargetScale) {
// Buffer initialized with yellow color
byte buffer[500];
memset(buffer, 2, sizeof(buffer));
@@ -249,7 +249,7 @@ void GFXtests::setupMouseLoop(bool disableCursorPalette, const char *gfxModeName
if (isFeaturePresent) {
- cursorRect = GFXtests::drawCursor(disableCursorPalette, gfxModeName, cursorTargetScale);
+ cursorRect = GFXtests::drawCursor(disableCursorPalette, cursorTargetScale);
Common::EventManager *eventMan = g_system->getEventManager();
Common::Event event;
@@ -741,7 +741,7 @@ TestExitStatus GFXtests::scaledCursors() {
if (isAspectRatioCorrected) {
info += "\nDisabling Aspect ratio correction, for letting cusors match exactly, will be restored after this test.";
}
-
+
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
Testsuite::logPrintf("Info! Skipping test : Scaled Cursors\n");
return kTestSkipped;
@@ -753,7 +753,7 @@ TestExitStatus GFXtests::scaledCursors() {
}
- if (isAspectRatioCorrected) {
+ if (isAspectRatioCorrected) {
g_system->beginGFXTransaction();
g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, false);
g_system->endGFXTransaction();
@@ -766,7 +766,7 @@ TestExitStatus GFXtests::scaledCursors() {
// for every graphics mode display cursors for cursorTargetScale 1, 2 and 3
// Switch Graphics mode
// FIXME: Crashes with "3x" mode now.:
-
+
info = Common::String::format("Testing : Scaled cursors with GFX Mode %s\n", gfxMode->name);
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
Testsuite::logPrintf("\tInfo! Skipping sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name);
@@ -779,7 +779,7 @@ TestExitStatus GFXtests::scaledCursors() {
Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n");
return kTestSkipped;
}
-
+
g_system->beginGFXTransaction();
bool isGFXModeSet = g_system->setGraphicsMode(gfxMode->id);
@@ -807,7 +807,7 @@ TestExitStatus GFXtests::scaledCursors() {
if (Testsuite::handleInteractiveInput(info, "Yes", "No", kOptionRight)) {
Testsuite::logPrintf("\tInfo! Failed sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name);
}
-
+
if (Engine::shouldQuit()) {
// Explicit exit requested
Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n");
@@ -824,7 +824,7 @@ TestExitStatus GFXtests::scaledCursors() {
if (isAspectRatioCorrected) {
g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, true);
}
-
+
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
if (gfxError != OSystem::kTransactionSuccess || !isGFXModeSet) {
@@ -962,13 +962,14 @@ TestExitStatus GFXtests::paletteRotation() {
Testsuite::logPrintf("Info! Skipping test : palette Rotation\n");
return kTestSkipped;
}
- Common::Point pt(0, 10);
+
Testsuite::clearEntireScreen();
// Use 256 colors
byte palette[256 * 3] = {0};
int r, g, b;
+ r = g = b = 0;
int colIndx;
for (int i = 0; i < 256; i++) {
@@ -1065,7 +1066,6 @@ TestExitStatus GFXtests::pixelFormats() {
}
Common::List<Graphics::PixelFormat> pfList = g_system->getSupportedFormats();
- Common::List<Graphics::PixelFormat>::const_iterator iter = pfList.begin();
int numFormatsTested = 0;
int numPassed = 0;
@@ -1073,7 +1073,7 @@ TestExitStatus GFXtests::pixelFormats() {
Testsuite::logDetailedPrintf("Testing Pixel Formats. Size of list : %d\n", pfList.size());
- for (iter = pfList.begin(); iter != pfList.end(); iter++) {
+ for (Common::List<Graphics::PixelFormat>::const_iterator iter = pfList.begin(); iter != pfList.end(); iter++) {
numFormatsTested++;
if (iter->bytesPerPixel == 1) {
// Palettes already tested
diff --git a/engines/testbed/graphics.h b/engines/testbed/graphics.h
index 7fa8f9d708..f3013fdf53 100644
--- a/engines/testbed/graphics.h
+++ b/engines/testbed/graphics.h
@@ -32,9 +32,9 @@ namespace GFXtests {
void drawEllipse(int x, int y, int a, int b);
void setupMouseLoop(bool disableCursorPalette = false, const char *gfxModeName = "", int cursorTargetScale = 1);
void initMousePalette();
-Common::Rect computeSize(Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale);
+Common::Rect computeSize(const Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale);
void HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, int val);
-Common::Rect drawCursor(bool cursorPaletteDisabled = false, const char *gfxModeName = "", int cursorTargetScale = 1);
+Common::Rect drawCursor(bool cursorPaletteDisabled = false, int cursorTargetScale = 1);
// will contain function declarations for GFX tests
TestExitStatus cursorTrails();
diff --git a/engines/testbed/midi.cpp b/engines/testbed/midi.cpp
index 54be866b4c..69d361b0d6 100644
--- a/engines/testbed/midi.cpp
+++ b/engines/testbed/midi.cpp
@@ -142,12 +142,12 @@ MidiTestSuite::MidiTestSuite() {
// add some fallback test if filesystem loading failed
Testsuite::logPrintf("Warning! Midi: Sound data file music.mid not found\n");
_isMidiDataFound = false;
- enable(false);
+ MidiTestSuite::enable(false);
}
}
void MidiTestSuite::enable(bool flag) {
- Testsuite::enable(_isMidiDataFound & flag);
+ Testsuite::enable(_isMidiDataFound ? flag : false);
}
}
diff --git a/engines/testbed/misc.cpp b/engines/testbed/misc.cpp
index 642e0b8ae2..034d3eb27e 100644
--- a/engines/testbed/misc.cpp
+++ b/engines/testbed/misc.cpp
@@ -24,7 +24,7 @@
namespace Testbed {
-Common::String MiscTests::getHumanReadableFormat(TimeDate &td) {
+Common::String MiscTests::getHumanReadableFormat(const TimeDate &td) {
return Common::String::format("%d:%d:%d on %d/%d/%d (dd/mm/yyyy)", td.tm_hour, td.tm_min, td.tm_sec, td.tm_mday, td.tm_mon + 1, td.tm_year + 1900);
}
diff --git a/engines/testbed/misc.h b/engines/testbed/misc.h
index 415fe82903..3f0772c6e5 100644
--- a/engines/testbed/misc.h
+++ b/engines/testbed/misc.h
@@ -40,7 +40,7 @@ namespace MiscTests {
// Miscellaneous tests include testing datetime, timers and mutexes
// Helper functions for Misc tests
-Common::String getHumanReadableFormat(TimeDate &td);
+Common::String getHumanReadableFormat(const TimeDate &td);
void timerCallback(void *arg);
void criticalSection(void *arg);
diff --git a/engines/testbed/savegame.cpp b/engines/testbed/savegame.cpp
index b19c8e3872..226e9880a6 100644
--- a/engines/testbed/savegame.cpp
+++ b/engines/testbed/savegame.cpp
@@ -133,11 +133,11 @@ TestExitStatus SaveGametests::testListingSavefile() {
writeDataToFile("tBedSavefileToList.1", "Save me!");
writeDataToFile("tBedSavefileToList.2", "Save me!");
- Common::Error error = saveFileMan->getError();
+ Common::Error err = saveFileMan->getError();
- if (error.getCode() != Common::kNoError) {
+ if (err.getCode() != Common::kNoError) {
// Abort. Some Error in writing files
- Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", error.getDesc().c_str());
+ Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", err.getDesc().c_str());
return kTestFailed;
}
@@ -158,11 +158,9 @@ TestExitStatus SaveGametests::testListingSavefile() {
}
}
return kTestPassed;
- } else {
- Testsuite::logDetailedPrintf("listing Savefiles failed!\n");
- return kTestFailed;
}
+ Testsuite::logDetailedPrintf("listing Savefiles failed!\n");
return kTestFailed;
}
@@ -173,8 +171,8 @@ TestExitStatus SaveGametests::testErrorMessages() {
// Try opening a non existing file
readAndVerifyData("tBedSomeNonExistentSaveFile.0", "File doesn't exists!");
- Common::Error error = saveFileMan->getError();
- if (error.getCode() == Common::kNoError) {
+ Common::Error err = saveFileMan->getError();
+ if (err.getCode() == Common::kNoError) {
// blunder! how come?
Testsuite::logDetailedPrintf("SaveFileMan.getError() failed\n");
return kTestFailed;
diff --git a/engines/testbed/sound.h b/engines/testbed/sound.h
index 76d0c7bb61..fea7d9d45b 100644
--- a/engines/testbed/sound.h
+++ b/engines/testbed/sound.h
@@ -69,10 +69,6 @@ public:
const char *getDescription() const {
return "Sound Subsystem";
}
-
-private:
- bool _isTestDataFound;
-
};
} // End of namespace Testbed
diff --git a/engines/testbed/testbed.cpp b/engines/testbed/testbed.cpp
index 41a705e292..152764eb27 100644
--- a/engines/testbed/testbed.cpp
+++ b/engines/testbed/testbed.cpp
@@ -76,12 +76,16 @@ void TestbedExitDialog::init() {
void TestbedExitDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
+ default:
+ break;
+
case kCmdRerunTestbed :
ConfParams.setRerunFlag(true);
cmd = GUI::kCloseCmd;
- default:
- GUI::Dialog::handleCommand(sender, cmd, data);
+ break;
}
+
+ GUI::Dialog::handleCommand(sender, cmd, data);
}
bool TestbedEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/testbed/testsuite.cpp b/engines/testbed/testsuite.cpp
index 77211b3e64..655179aa74 100644
--- a/engines/testbed/testsuite.cpp
+++ b/engines/testbed/testsuite.cpp
@@ -113,7 +113,7 @@ bool Testsuite::handleInteractiveInput(const Common::String &textToDisplay, cons
return prompt.runModal() == result ? true : false;
}
-void Testsuite::displayMessage(const Common::String &textToDisplay, const char *defaultButton, const char *altButton) {
+void Testsuite::displayMessage(const Common::String &textToDisplay, const char *defaultButton) {
GUI::MessageDialog prompt(textToDisplay, defaultButton);
prompt.runModal();
}
@@ -214,10 +214,11 @@ uint Testsuite::parseEvents() {
return kSkipNext;
}
break;
+
case Common::EVENT_QUIT:
case Common::EVENT_RTL:
return kEngineQuit;
- break;
+
default:
break;
}
diff --git a/engines/testbed/testsuite.h b/engines/testbed/testsuite.h
index 3a3a78b9bb..dc159ce25f 100644
--- a/engines/testbed/testsuite.h
+++ b/engines/testbed/testsuite.h
@@ -112,7 +112,7 @@ public:
*/
static bool handleInteractiveInput(const Common::String &textToDisplay, const char *opt1 = "Yes", const char *opt2 = "No", OptionSelected result = kOptionLeft);
- static void displayMessage(const Common::String &textToDisplay, const char *defaultButton = "OK", const char *altButton = 0);
+ static void displayMessage(const Common::String &textToDisplay, const char *defaultButton = "OK");
static Common::Rect writeOnScreen(const Common::String &textToDisplay, const Common::Point &pt, bool flag = false);
static void clearScreen(const Common::Rect &rect);
static void clearEntireScreen() {
@@ -145,7 +145,7 @@ public:
static void logPrintf(const char *s, ...) GCC_PRINTF(1, 2);
static void logDetailedPrintf(const char *s, ...) GCC_PRINTF(1, 2);
-
+
// Progress bar (Information Display) related methods.
/**
* Display region is in the bottom. Probably 1/4th of the game screen.
@@ -180,7 +180,7 @@ protected:
bool _isTsEnabled;
private:
-
+
/**
* Used from the code to decide if the engine needs to exit
*/
diff --git a/engines/tinsel/coroutine.h b/engines/tinsel/coroutine.h
index b62c40b4e5..5bcf1149d9 100644
--- a/engines/tinsel/coroutine.h
+++ b/engines/tinsel/coroutine.h
@@ -178,10 +178,15 @@ public:
#define CORO_RESCHEDULE do { g_scheduler->reschedule(); CORO_SLEEP(1); } while (0)
/**
- * Stop the currently running coroutine.
+ * Stop the currently running coroutine and all calling coroutines.
+ *
+ * This sets _sleep to -1 rather than 0 so that the context doesn't get
+ * deleted by CoroContextHolder, since we want CORO_INVOKE_ARGS to
+ * propogate the _sleep value and return immediately (the scheduler will
+ * then delete the entire coroutine's state, including all subcontexts).
*/
#define CORO_KILL_SELF() \
- do { if (&coroParam != &nullContext) { coroParam->_sleep = 0; } return; } while (0)
+ do { if (&coroParam != &nullContext) { coroParam->_sleep = -1; } return; } while (0)
/**
@@ -193,8 +198,12 @@ public:
/**
* Invoke another coroutine.
*
- * What makes this tricky is that the coroutine we called my yield/sleep,
- * and we need to deal with this adequately.
+ * If the subcontext still exists after the coroutine is invoked, it has
+ * either yielded/slept or killed itself, and so we copy the _sleep value
+ * to our own context and return (execution will continue at the case
+ * statement below, where we loop and call the coroutine again).
+ * If the subcontext is null, the coroutine ended normally, and we can
+ * simply break out of the loop and continue execution.
*
* @param subCoro name of the coroutine-enabled function to invoke
* @param ARGS list of arguments to pass to subCoro
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index 0f0e3cd1ef..9c52305a1c 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -63,7 +63,7 @@ uint16 TinselEngine::getVersion() const {
return _gameDescription->version;
}
-}
+} // End of namespace Tinsel
static const PlainGameDescriptor tinselGames[] = {
{"tinsel", "Tinsel engine game"},
@@ -74,34 +74,11 @@ static const PlainGameDescriptor tinselGames[] = {
#include "tinsel/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Tinsel::gameDescriptions,
- // Size of that superset structure
- sizeof(Tinsel::TinselGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- tinselGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "tinsel",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class TinselMetaEngine : public AdvancedMetaEngine {
public:
- TinselMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ TinselMetaEngine() : AdvancedMetaEngine(Tinsel::gameDescriptions, sizeof(Tinsel::TinselGameDescription), tinselGames) {
+ _singleid = "tinsel";
+ }
virtual const char *getName() const {
return "Tinsel";
@@ -112,7 +89,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
- const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const;
+ const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
virtual bool hasFeature(MetaEngineFeature f) const;
virtual SaveStateList listSaves(const char *target) const;
@@ -198,7 +175,7 @@ typedef Common::Array<const ADGameDescription*> ADGameDescList;
* Fallback detection scans the list of Discworld 2 targets to see if it can detect an installation
* where the files haven't been renamed (i.e. don't have the '1' just before the extension)
*/
-const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
+const ADGameDescription *TinselMetaEngine::fallbackDetect(const FileMap &allFilesXXX, const Common::FSList &fslist) const {
Common::String extra;
FileMap allFiles;
SizeMD5Map filesSizeMD5;
@@ -265,7 +242,7 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &
if (testFile.open(allFiles[fname])) {
tmp.size = (int32)testFile.size();
- tmp.md5 = computeStreamMD5AsString(testFile, detectionParams.md5Bytes);
+ tmp.md5 = computeStreamMD5AsString(testFile, _md5Bytes);
} else {
tmp.size = -1;
}
@@ -285,11 +262,6 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &
bool fileMissing = false;
- if ((detectionParams.flags & kADFlagUseExtraAsHint) && !extra.empty() && g->desc.extra != extra)
- continue;
-
- bool allFilesPresent = true;
-
// Try to match all files for this game
for (fileDesc = g->desc.filesDescriptions; fileDesc->fileName; fileDesc++) {
// Get the next filename, stripping off any '1' suffix character
@@ -307,7 +279,6 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &
if (!filesSizeMD5.contains(tstr)) {
fileMissing = true;
- allFilesPresent = false;
break;
}
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index c86db9e438..116322aa89 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -119,7 +119,7 @@ static const TinselGameDescription gameDescriptions[] = {
TINSEL_V1,
},
- {
+ {
{
"dw",
"Floppy",
@@ -142,7 +142,7 @@ static const TinselGameDescription gameDescriptions[] = {
TINSEL_V1,
},
- {
+ {
{
"dw",
"Floppy",
@@ -165,7 +165,7 @@ static const TinselGameDescription gameDescriptions[] = {
TINSEL_V1,
},
- {
+ {
{
"dw",
"Floppy",
diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp
index 0834e7df24..2ab1e653d4 100644
--- a/engines/tinsel/pcode.cpp
+++ b/engines/tinsel/pcode.cpp
@@ -140,11 +140,11 @@ static const byte fragment7[] = {OP_IMM | OPSIZE16, FRAGMENT_WORD(908), OP_JUMP
static const byte fragment8[] = {OP_IMM | OPSIZE16, FRAGMENT_WORD(910), OP_JUMP | OPSIZE16, FRAGMENT_WORD(644)};
static const byte fragment9[] = {OP_JUMP | OPSIZE8, 123};
static const byte fragment10[] = {OP_IMM | OPSIZE16, FRAGMENT_WORD(160), OP_JUMP | OPSIZE16, FRAGMENT_WORD(136)};
-static const byte fragment11[] = {OP_JMPTRUE | OPSIZE16, FRAGMENT_WORD(1572),
+static const byte fragment11[] = {OP_JMPTRUE | OPSIZE16, FRAGMENT_WORD(1572),
OP_ONE, OP_LIBCALL | OPSIZE8, 14, // Re-show the cursor
OP_IMM | OPSIZE16, FRAGMENT_WORD(322), OP_LIBCALL | OPSIZE8, 46, // Give back the whistle
OP_JUMP | OPSIZE16, FRAGMENT_WORD(1661)};
-static const byte fragment12[] = {OP_JMPTRUE | OPSIZE16, FRAGMENT_WORD(1491),
+static const byte fragment12[] = {OP_JMPTRUE | OPSIZE16, FRAGMENT_WORD(1491),
OP_ONE, OP_LIBCALL | OPSIZE8, 14, // Re-show the cursor
OP_IMM | OPSIZE16, FRAGMENT_WORD(322), OP_LIBCALL | OPSIZE8, 46, // Give back the whistle
OP_JUMP | OPSIZE16, FRAGMENT_WORD(1568)};
@@ -208,10 +208,10 @@ const WorkaroundEntry workaroundList[] = {
// See bug report #2934211.
{TINSEL_V1, true, 352601285, 1569, sizeof(fragment11), fragment11},
{TINSEL_V1, false, 352602304, 1488, sizeof(fragment12), fragment12},
-
+
// DW2: Corrects a bug with global 306 not being cleared if you leave
// the marketplace scene whilst D'Blah is talking (even if it's not
- // actually audible); returning to the scene and clicking on him multiple
+ // actually audible); returning to the scene and clicking on him multiple
// times would cause the game to crash
{TINSEL_V2, true, 1109294728, 0, sizeof(fragment13), fragment13},
diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp
index caaf9a13f8..7a973ba4be 100644
--- a/engines/tinsel/saveload.cpp
+++ b/engines/tinsel/saveload.cpp
@@ -34,6 +34,7 @@
#include "common/serializer.h"
#include "common/savefile.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "gui/message.h"
@@ -464,7 +465,7 @@ static bool DoRestore() {
delete f;
if (failed) {
- GUI::MessageDialog dialog("Failed to load game state from file.");
+ GUI::MessageDialog dialog(_("Failed to load game state from file."));
dialog.runModal();
}
@@ -482,7 +483,7 @@ static void DoSave() {
NeedLoad = true;
if (SaveSceneName == NULL) {
- // Generate a new unique save name
+ // Generate a new unique save name
int i;
int ano = 1; // Allocated number
@@ -542,7 +543,7 @@ save_failure:
_vm->getSaveFileMan()->removeSavefile(SaveSceneName);
SaveSceneName = NULL; // Invalidate save name
}
- GUI::MessageDialog dialog("Failed to save game state to file.");
+ GUI::MessageDialog dialog(_("Failed to save game state to file."));
dialog.runModal();
}
diff --git a/engines/tinsel/sched.cpp b/engines/tinsel/sched.cpp
index b24d6bf9b8..d6cd806eb2 100644
--- a/engines/tinsel/sched.cpp
+++ b/engines/tinsel/sched.cpp
@@ -70,6 +70,7 @@ Scheduler::Scheduler() {
active = new PROCESS;
active->pPrevious = NULL;
+ active->pNext = NULL;
g_scheduler = this; // FIXME HACK
}
@@ -113,6 +114,14 @@ void Scheduler::reset() {
memset(processList, 'S', MAX_PROCESSES * sizeof(PROCESS));
}
+ // Kill all running processes (i.e. free memory allocated for their state).
+ PROCESS *pProc = active->pNext;
+ while (pProc != NULL) {
+ delete pProc->state;
+ pProc->state = 0;
+ pProc = pProc->pNext;
+ }
+
// no active processes
pCurrent = active->pNext = NULL;
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 7613c1a897..7fbec69cbf 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -214,39 +214,39 @@ static const MASTER_LIB_CODES DW1_CODES[] = {
};
static const MASTER_LIB_CODES DW2DEMO_CODES[] = {
- ACTORBRIGHTNESS, ACTORDIRECTION, ACTORPALETTE, ACTORPRIORITY,
+ ACTORBRIGHTNESS, ACTORDIRECTION, ACTORPALETTE, ACTORPRIORITY,
ACTORREF, ACTORRGB, ACTORSCALE, ACTORXPOS, ACTORYPOS,
ADDHIGHLIGHT, ADDINV, ADDINV1, ADDINV2, ADDOPENINV, ADDTOPIC,
- BACKGROUND, CALLACTOR, CALLGLOBALPROCESS, CALLOBJECT,
+ BACKGROUND, CALLACTOR, CALLGLOBALPROCESS, CALLOBJECT,
CALLPROCESS, CALLSCENE, CALLTAG, CAMERA, CDCHANGESCENE,
CDDOCHANGE, CDLOAD, CDPLAY, CLEARHOOKSCENE, CLOSEINVENTORY,
- CONTROL, CONVERSATION, CURSOR, CURSORXPOS, CURSORYPOS,
- DECCONVW, DECCURSOR, DECFLAGS, DECINV1, DECINV2, DECINVW,
+ CONTROL, CONVERSATION, CURSOR, CURSORXPOS, CURSORYPOS,
+ DECCONVW, DECCURSOR, DECFLAGS, DECINV1, DECINV2, DECINVW,
DECLEAD, DECSCALE, DECTAGFONT, DECTALKFONT, DELTOPIC,
DIMMUSIC, DROP, DROPOUT, EFFECTACTOR, ENABLEMENU, ENDACTOR,
- ESCAPEOFF, ESCAPEON, EVENT, FACETAG, FADEIN, FADEOUT, FRAMEGRAB,
- FREEZECURSOR, GETINVLIMIT, GHOST, GLOBALVAR, HASRESTARTED,
- HAVE, HELDOBJECT, HIDEACTOR, HIDEBLOCK, HIDEEFFECT, HIDEPATH,
+ ESCAPEOFF, ESCAPEON, EVENT, FACETAG, FADEIN, FADEOUT, FRAMEGRAB,
+ FREEZECURSOR, GETINVLIMIT, GHOST, GLOBALVAR, HASRESTARTED,
+ HAVE, HELDOBJECT, HIDEACTOR, HIDEBLOCK, HIDEEFFECT, HIDEPATH,
HIDEREFER, HIDETAG, HOLD, HOOKSCENE, IDLETIME, INSTANTSCROLL,
- INVENTORY, INVPLAY, INWHICHINV, KILLACTOR, KILLGLOBALPROCESS,
- KILLPROCESS, LOCALVAR, MOVECURSOR, MOVETAG, MOVETAGTO, NEWSCENE,
- NOBLOCKING, NOPAUSE, NOSCROLL, OFFSET, OTHEROBJECT, PAUSE, PLAY,
- PLAYMUSIC, PLAYRTF, PLAYSAMPLE, POINTACTOR, POINTTAG, POSTACTOR,
+ INVENTORY, INVPLAY, INWHICHINV, KILLACTOR, KILLGLOBALPROCESS,
+ KILLPROCESS, LOCALVAR, MOVECURSOR, MOVETAG, MOVETAGTO, NEWSCENE,
+ NOBLOCKING, NOPAUSE, NOSCROLL, OFFSET, OTHEROBJECT, PAUSE, PLAY,
+ PLAYMUSIC, PLAYRTF, PLAYSAMPLE, POINTACTOR, POINTTAG, POSTACTOR,
POSTGLOBALPROCESS, POSTOBJECT, POSTPROCESS, POSTTAG, PRINT,
PRINTCURSOR, PRINTOBJ, PRINTTAG, QUITGAME, RANDOM, RESETIDLETIME,
- RESTARTGAME, RESTORESCENE, RUNMODE, SAVESCENE, SAY, SAYAT,
- SCALINGREELS, SCREENXPOS, SCREENYPOS, SCROLL, SCROLLPARAMETERS,
+ RESTARTGAME, RESTORESCENE, RUNMODE, SAVESCENE, SAY, SAYAT,
+ SCALINGREELS, SCREENXPOS, SCREENYPOS, SCROLL, SCROLLPARAMETERS,
SENDACTOR, SENDGLOBALPROCESS, SENDOBJECT, SENDPROCESS, SENDTAG,
- SETBRIGHTNESS, SETINVLIMIT, SETINVSIZE, SETLANGUAGE, SETPALETTE,
- SETSYSTEMSTRING, SETSYSTEMVAR, SHELL, SHOWACTOR, SHOWBLOCK,
+ SETBRIGHTNESS, SETINVLIMIT, SETINVSIZE, SETLANGUAGE, SETPALETTE,
+ SETSYSTEMSTRING, SETSYSTEMVAR, SHELL, SHOWACTOR, SHOWBLOCK,
SHOWEFFECT, SHOWPATH, SHOWREFER, SHOWTAG, STAND, STANDTAG,
- STARTGLOBALPROCESS, STARTPROCESS, STARTTIMER, STOPWALK, SUBTITLES,
- SWALK, SYSTEMVAR, TAGTAGXPOS, TAGTAGYPOS, TAGWALKXPOS, TAGWALKYPOS,
+ STARTGLOBALPROCESS, STARTPROCESS, STARTTIMER, STOPWALK, SUBTITLES,
+ SWALK, SYSTEMVAR, TAGTAGXPOS, TAGTAGYPOS, TAGWALKXPOS, TAGWALKYPOS,
TALK, TALKAT, TALKPALETTEINDEX, TALKRGB, TALKVIA, THISOBJECT,
- THISTAG, TIMER, TOPIC, TOPPLAY, TOPWINDOW, TRANSLUCENTINDEX,
- UNDIMMUSIC, UNHOOKSCENE, WAITFRAME, WAITKEY, WAITSCROLL, WAITTIME,
- WALK, WALKED, WALKEDPOLY, WALKEDTAG, WALKINGACTOR, WALKPOLY,
- WALKTAG, WALKXPOS, WALKYPOS, WHICHCD, WHICHINVENTORY,
+ THISTAG, TIMER, TOPIC, TOPPLAY, TOPWINDOW, TRANSLUCENTINDEX,
+ UNDIMMUSIC, UNHOOKSCENE, WAITFRAME, WAITKEY, WAITSCROLL, WAITTIME,
+ WALK, WALKED, WALKEDPOLY, WALKEDTAG, WALKINGACTOR, WALKPOLY,
+ WALKTAG, WALKXPOS, WALKYPOS, WHICHCD, WHICHINVENTORY,
HIGHEST_LIBCODE
};
diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp
index 23bd0f6487..07d51ef1b9 100644
--- a/engines/toon/anim.cpp
+++ b/engines/toon/anim.cpp
@@ -271,6 +271,18 @@ void Animation::applyPalette(int32 offset, int32 srcOffset, int32 numEntries) {
_vm->setPaletteEntries(_palette + srcOffset, offset, numEntries);
}
+Common::Rect Animation::getFrameRect(int32 frame) {
+ debugC(4, kDebugAnim, "getFrameRect(%d)", frame);
+ if ((frame < 0) || (frame >= _numFrames)) {
+ return Common::Rect();
+ }
+
+ if (_frames[frame]._ref != -1)
+ frame = _frames[frame]._ref;
+
+ return Common::Rect(_frames[frame]._x1, _frames[frame]._y1, _frames[frame]._x2, _frames[frame]._y2);
+}
+
int32 Animation::getFrameWidth(int32 frame) {
debugC(4, kDebugAnim, "getFrameWidth(%d)", frame);
if ((frame < 0) || (frame >= _numFrames))
diff --git a/engines/toon/anim.h b/engines/toon/anim.h
index 13c501b910..4b95b6cf40 100644
--- a/engines/toon/anim.h
+++ b/engines/toon/anim.h
@@ -68,6 +68,7 @@ public:
void drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 frame, int32 xx, int32 yy, int32 zz, Picture *mask, int32 scale);
void drawStrip(int32 offset = 0);
void applyPalette(int32 offset, int32 srcOffset, int32 numEntries);
+ Common::Rect getFrameRect(int32 frame);
int32 getFrameWidth(int32 frame);
int32 getFrameHeight(int32 frame);
int32 getWidth() const;
diff --git a/engines/toon/detection.cpp b/engines/toon/detection.cpp
index 1056f6ec0d..810a37720a 100644
--- a/engines/toon/detection.cpp
+++ b/engines/toon/detection.cpp
@@ -28,7 +28,7 @@
#include "graphics/thumbnail.h"
#include "toon/toon.h"
-static const PlainGameDescriptor ToonGames[] = {
+static const PlainGameDescriptor toonGames[] = {
{ "toon", "Toonstruck" },
{ 0, 0 }
};
@@ -117,34 +117,17 @@ static const char * const directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Toon::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- ToonGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "toon",
- // List of files for file-based fallback detection (optional)
- Toon::fileBasedFallback,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 3,
- // List of directory globs
- directoryGlobs
-};
-
class ToonMetaEngine : public AdvancedMetaEngine {
public:
- ToonMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ ToonMetaEngine() : AdvancedMetaEngine(Toon::gameDescriptions, sizeof(ADGameDescription), toonGames) {
+ _singleid = "toon";
+ _maxScanDepth = 3;
+ _directoryGlobs = directoryGlobs;
+ }
+
+ virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
+ return detectGameFilebased(allFiles, Toon::fileBasedFallback);
+ }
virtual const char *getName() const {
return "Toon";
diff --git a/engines/toon/font.cpp b/engines/toon/font.cpp
index 4c491ae2b3..63304c905f 100644
--- a/engines/toon/font.cpp
+++ b/engines/toon/font.cpp
@@ -21,6 +21,7 @@
*/
#include "common/debug.h"
+#include "common/rect.h"
#include "toon/font.h"
@@ -80,7 +81,7 @@ void FontRenderer::renderText(int32 x, int32 y, Common::String origText, int32 m
x -= xx / 2;
}
- _vm->addDirtyRect(x, y, x + xx + 2, y + yy);
+ _vm->addDirtyRect(x, y, x + xx, y + yy);
int32 curX = x;
int32 curY = y;
@@ -110,6 +111,7 @@ void FontRenderer::computeSize(Common::String origText, int32 *retX, int32 *retY
int32 lineHeight = 0;
int32 totalHeight = 0;
int32 totalWidth = 0;
+ int32 lastLineHeight = 0;
const byte *text = (const byte *)origText.c_str();
while (*text) {
@@ -122,17 +124,25 @@ void FontRenderer::computeSize(Common::String origText, int32 *retX, int32 *retY
totalHeight += lineHeight;
lineHeight = 0;
lineWidth = 0;
+ lastLineHeight = 0;
} else {
curChar = textToFont(curChar);
int32 charWidth = _currentFont->getFrameWidth(curChar) - 1;
int32 charHeight = _currentFont->getFrameHeight(curChar);
lineWidth += charWidth;
lineHeight = MAX(lineHeight, charHeight);
+
+ // The character may be offset, so the height doesn't
+ // really tell how far it will stick out. For now,
+ // assume we only need to take the lower bound into
+ // consideration.
+ Common::Rect charRect = _currentFont->getFrameRect(curChar);
+ lastLineHeight = MAX<int32>(lastLineHeight, charRect.bottom);
}
text++;
}
- totalHeight += lineHeight;
+ totalHeight += lastLineHeight;
totalWidth = MAX(totalWidth, lineWidth);
*retX = totalWidth;
diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp
index c116d63663..43a134e39b 100644
--- a/engines/toon/path.cpp
+++ b/engines/toon/path.cpp
@@ -342,8 +342,15 @@ next:
curX = destx;
curY = desty;
- int32 retPathX[4096];
- int32 retPathY[4096];
+ int32 *retPathX = (int32 *)malloc(4096 * sizeof(int32));
+ int32 *retPathY = (int32 *)malloc(4096 * sizeof(int32));
+ if (!retPathX || !retPathY) {
+ free(retPathX);
+ free(retPathY);
+
+ error("[PathFinding::findPath] Cannot allocate pathfinding buffers");
+ }
+
int32 numpath = 0;
retPathX[numpath] = curX;
@@ -377,8 +384,12 @@ next:
}
}
- if (bestX < 0 || bestY < 0)
+ if (bestX < 0 || bestY < 0) {
+ free(retPathX);
+ free(retPathY);
+
return 0;
+ }
retPathX[numpath] = bestX;
retPathY[numpath] = bestY;
@@ -389,6 +400,10 @@ next:
memcpy(_tempPathX, retPathX, sizeof(int32) * numpath);
memcpy(_tempPathY, retPathY, sizeof(int32) * numpath);
+
+ free(retPathX);
+ free(retPathY);
+
return true;
}
@@ -396,6 +411,9 @@ next:
curY = bestY;
}
+ free(retPathX);
+ free(retPathY);
+
return false;
}
@@ -406,8 +424,8 @@ void PathFinding::init(Picture *mask) {
_height = mask->getHeight();
_currentMask = mask;
_heap->unload();
- // In order to reduce memory fragmentation on small devices, we use the maximum
- // possible size here which is TOON_BACKBUFFER_WIDTH. Even though this is
+ // In order to reduce memory fragmentation on small devices, we use the maximum
+ // possible size here which is TOON_BACKBUFFER_WIDTH. Even though this is
// 1280 as opposed to the possible 640, it actually helps memory allocation on
// those devices.
_heap->init(TOON_BACKBUFFER_WIDTH * _height); // should really be _width
diff --git a/engines/toon/tools.cpp b/engines/toon/tools.cpp
index c9aa470deb..c2ee8acf8a 100644
--- a/engines/toon/tools.cpp
+++ b/engines/toon/tools.cpp
@@ -372,7 +372,7 @@ int32 RncDecoder::unpackM1(const void *input, uint16 inputSize, void *output) {
_dstPtr += inputLength;
_srcPtr += inputLength;
_inputByteLeft -= inputLength;
- uint16 a;
+ uint16 a;
if (_inputByteLeft <= 0)
a = 0;
else if (_inputByteLeft == 1)
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 93da20fb47..26639d71f7 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -28,6 +28,7 @@
#include "common/savefile.h"
#include "common/memstream.h"
+#include "engines/advancedDetector.h"
#include "engines/util.h"
#include "graphics/palette.h"
#include "graphics/surface.h"
@@ -113,7 +114,7 @@ void ToonEngine::init() {
_drew = _characters[0];
_flux = _characters[1];
-
+
// preload walk anim for flux and drew
_drew->loadWalkAnimation("STNDWALK.CAF");
@@ -2694,7 +2695,7 @@ int32 ToonEngine::showInventory() {
}
renderInventory();
-
+ _system->delayMillis(10);
}
_gameState->_currentScrollValue = oldScrollValue;
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index 02828f26d1..cad684d590 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -23,7 +23,6 @@
#ifndef TOON_TOON_H
#define TOON_TOON_H
-#include "engines/advancedDetector.h"
#include "engines/engine.h"
#include "graphics/surface.h"
#include "common/random.h"
@@ -44,6 +43,8 @@ namespace Common {
class MemoryWriteStreamDynamic;
}
+struct ADGameDescription;
+
#define TOON_DAT_VER_MAJ 0 // 1 byte
#define TOON_DAT_VER_MIN 3 // 1 byte
#define TOON_SAVEGAME_VERSION 4
@@ -203,7 +204,7 @@ public:
void viewInventoryItem(Common::String str, int32 lineId, int32 itemDest);
void storePalette();
void restorePalette();
- const char *getSpecialConversationMusic(int32 locationId);
+ const char *getSpecialConversationMusic(int32 locationId);
void playRoomMusic();
void waitForScriptStep();
void doMagnifierEffect();
@@ -319,7 +320,7 @@ public:
}
Common::Error saveGameState(int slot, const Common::String &desc) {
-
+
return (saveGame(slot, desc) ? Common::kWritingFailed : Common::kNoError);
}
@@ -380,7 +381,7 @@ protected:
Common::Array<Common::Rect> _oldDirtyRects;
bool _dirtyAll;
-
+
AnimationInstance *_cursorAnimationInstance;
Animation *_cursorAnimation;
diff --git a/engines/touche/detection.cpp b/engines/touche/detection.cpp
index b7f9c092aa..0684144473 100644
--- a/engines/touche/detection.cpp
+++ b/engines/touche/detection.cpp
@@ -24,6 +24,7 @@
#include "engines/advancedDetector.h"
#include "common/savefile.h"
#include "common/system.h"
+#include "common/translation.h"
#include "base/plugins.h"
@@ -126,34 +127,31 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Touche::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 4096,
- // List of all engine targets
- toucheGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "touche",
- // List of files for file-based fallback detection (optional)
- Touche::fileBasedFallback,
- // Flags
- kADFlagPrintWarningOnFileBasedFallback,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class ToucheMetaEngine : public AdvancedMetaEngine {
public:
- ToucheMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ ToucheMetaEngine() : AdvancedMetaEngine(Touche::gameDescriptions, sizeof(ADGameDescription), toucheGames) {
+ _md5Bytes = 4096;
+ _singleid = "touche";
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ }
+
+ virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
+ const ADGameDescription *matchedDesc = detectGameFilebased(allFiles, Touche::fileBasedFallback);
+
+ if (matchedDesc) { // We got a match
+ Common::String report = Common::String::format(_("Your game version has been detected using "
+ "filename matching as a variant of %s."), matchedDesc->gameid);
+ report += "\n";
+ report += _("If this is an original and unmodified version, please report any");
+ report += "\n";
+ report += _("information previously printed by ScummVM to the team.");
+ report += "\n";
+ g_system->logMessage(LogMessageType::kInfo, report.c_str());
+ }
+
+ return matchedDesc;
+ }
virtual const char *getName() const {
return "Touche";
diff --git a/engines/touche/menu.cpp b/engines/touche/menu.cpp
index f469a95803..c58e2f1a33 100644
--- a/engines/touche/menu.cpp
+++ b/engines/touche/menu.cpp
@@ -103,7 +103,7 @@ struct MenuData {
void addCharToDescription(int slot, char chr) {
char *description = saveLoadDescriptionsTable[slot];
int descriptionLen = strlen(description);
- if (descriptionLen < 32 && isprint(chr)) {
+ if (descriptionLen < 32 && isprint(static_cast<unsigned char>(chr))) {
description[descriptionLen] = chr;
description[descriptionLen + 1] = 0;
}
diff --git a/engines/touche/resource.cpp b/engines/touche/resource.cpp
index 8f4752e912..6df6fc0e5f 100644
--- a/engines/touche/resource.cpp
+++ b/engines/touche/resource.cpp
@@ -468,14 +468,22 @@ void ToucheEngine::res_loadSprite(int num, int index) {
if (size > spr->size) {
debug(8, "Reallocating memory for sprite %d (index %d), %d bytes needed", num, index, size - spr->size);
spr->size = size;
- if (spr->ptr) {
- spr->ptr = (uint8 *)realloc(spr->ptr, size);
- } else {
- spr->ptr = (uint8 *)malloc(size);
- }
- if (!spr->ptr) {
- error("Unable to reallocate memory for sprite %d (%d bytes)", num, size);
+
+ uint8 *buffer = NULL;
+ if (spr->ptr)
+ buffer = (uint8 *)realloc(spr->ptr, size);
+
+ if (!buffer) {
+ // Free previously allocated sprite (when realloc failed)
+ free(spr->ptr);
+
+ buffer = (uint8 *)malloc(size);
}
+
+ if (!buffer)
+ error("[ToucheEngine::res_loadSprite] Unable to reallocate memory for sprite %d (%d bytes)", num, size);
+
+ spr->ptr = buffer;
}
for (int i = 0; i < _currentImageHeight; ++i) {
res_decodeScanLineImageRLE(spr->ptr + _currentImageWidth * i, _currentImageWidth);
diff --git a/engines/touche/touche.h b/engines/touche/touche.h
index 7e1aa3ac44..cbb3fec7aa 100644
--- a/engines/touche/touche.h
+++ b/engines/touche/touche.h
@@ -385,8 +385,6 @@ public:
protected:
- bool detectGame();
-
void restart();
void readConfigurationSettings();
void writeConfigurationSettings();
diff --git a/engines/tsage/blueforce_logic.cpp b/engines/tsage/blueforce_logic.cpp
index 9813bef6f7..d266d5e1d9 100644
--- a/engines/tsage/blueforce_logic.cpp
+++ b/engines/tsage/blueforce_logic.cpp
@@ -30,7 +30,7 @@ namespace tSage {
void BlueForceGame::start() {
// Start the game
_globals->_sceneManager.changeScene(20);
-
+
_globals->_events.setCursor(CURSOR_WALK);
}
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index 5fa36142e7..b475310533 100644
--- a/engines/tsage/converse.cpp
+++ b/engines/tsage/converse.cpp
@@ -231,7 +231,7 @@ void SequenceManager::signal() {
case 26:
v1 = getNextValue();
v2 = getNextValue();
- _soundHandler.startSound(v1, v2 ? this : NULL, 127);
+ _soundHandler.play(v1, v2 ? this : NULL, 127);
break;
case 27: {
v1 = getNextValue();
diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h
index 6876fa41cb..13c490e995 100644
--- a/engines/tsage/converse.h
+++ b/engines/tsage/converse.h
@@ -25,6 +25,7 @@
#include "tsage/core.h"
#include "tsage/dialogs.h"
+#include "tsage/sound.h"
namespace tSage {
@@ -50,7 +51,7 @@ public:
int _objectIndex;
SceneObject *_sceneObject;
SceneObject *_objectList[6];
- SoundHandler _soundHandler;
+ ASound _soundHandler;
public:
SequenceManager();
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index b929beec23..76714a6f10 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -31,6 +31,7 @@
#include "tsage/scenes.h"
#include "tsage/staticres.h"
#include "tsage/globals.h"
+#include "tsage/sound.h"
namespace tSage {
@@ -521,24 +522,30 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo
break;
}
- int var6;
- proc1(routeRegions, srcRegion, destRegion, var6);
+ bool tempVar; // This is used only as internal state for the function.
+ calculateRestOfRoute(routeRegions, srcRegion, destRegion, tempVar);
+ // Empty route?
if (!routeRegions[0]) {
regionIndexes.push_back(destRegion);
continue;
}
- _globals->_walkRegions._field18[0]._pt1 = srcPos;
- _globals->_walkRegions._field18[0]._pt2 = srcPos;
- _globals->_walkRegions._field18[1]._pt1 = destPos;
- _globals->_walkRegions._field18[1]._pt2 = destPos;
+ // field 0 holds the start, and field 1 holds the destination
+ WRField18 &currSrcField = _globals->_walkRegions._field18[0];
+ WRField18 &currDestField = _globals->_walkRegions._field18[1];
+
+ currSrcField._pt1 = srcPos;
+ currSrcField._pt2 = srcPos;
+ currDestField._pt1 = destPos;
+ currDestField._pt2 = destPos;
int tempList[REGION_LIST_SIZE];
tempList[0] = 0;
int endIndex = 0;
int idx = 1;
+ // Find the indexes for each entry in the found route.
do {
int breakEntry = routeRegions[idx];
int breakEntry2 = routeRegions[idx + 1];
@@ -556,49 +563,52 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo
tempList[idx] = 1;
for (int listIndex = 1; listIndex <= endIndex; ++listIndex) {
- int var10 = tempList[listIndex];
- int var12 = tempList[listIndex + 1];
+ int thisIdx = tempList[listIndex];
+ int nextIdx = tempList[listIndex + 1];
+
+ WRField18 &thisField = _globals->_walkRegions._field18[thisIdx];
+ WRField18 &nextField = _globals->_walkRegions._field18[nextIdx];
- if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt1,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2) &&
- sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt2,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2))
+ if (sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt1,
+ thisField._pt1, thisField._pt2) &&
+ sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt2,
+ thisField._pt1, thisField._pt2))
continue;
Common::Point tempPt;
- if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[1]._pt1,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2, &tempPt)) {
+ if (sub_F8E5_calculatePoint(currSrcField._pt1, currDestField._pt1,
+ thisField._pt1, thisField._pt2, &tempPt)) {
// Add point to the route list
- _globals->_walkRegions._field18[0]._pt1 = tempPt;
+ currSrcField._pt1 = tempPt;
*routeList++ = tempPt;
} else {
- int v16 =
- (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt1) << 1) +
- (findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[1]._pt1) << 1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt2);
-
- int v1A =
- (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt2) << 1) +
- (findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[1]._pt2) << 1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt2);
-
- if (v16 < v1A) {
- checkMovement2(_globals->_walkRegions._field18[var10]._pt1,
- _globals->_walkRegions._field18[var10]._pt2, 1, objPos);
+ int dist1 =
+ (findDistance(currSrcField._pt1, thisField._pt1) << 1) +
+ (findDistance(thisField._pt1, currDestField._pt1) << 1) +
+ findDistance(thisField._pt1, nextField._pt1) +
+ findDistance(thisField._pt1, nextField._pt2);
+
+ int dist2 =
+ (findDistance(currSrcField._pt1, thisField._pt2) << 1) +
+ (findDistance(thisField._pt2, currDestField._pt2) << 1) +
+ findDistance(thisField._pt2, nextField._pt1) +
+ findDistance(thisField._pt2, nextField._pt2);
+
+ // Do 1 step of movement, storing the new position in objPos.
+ if (dist1 < dist2) {
+ doStepsOfNpcMovement(thisField._pt1, thisField._pt2, 1, objPos);
} else {
- checkMovement2(_globals->_walkRegions._field18[var10]._pt2,
- _globals->_walkRegions._field18[var10]._pt1, 1, objPos);
+ doStepsOfNpcMovement(thisField._pt2, thisField._pt1, 1, objPos);
}
- _globals->_walkRegions._field18[0]._pt1 = objPos;
+ // Update the current position.
+ currSrcField._pt1 = objPos;
*routeList++ = objPos;
}
}
// Add in the route entry
- *routeList++ = _globals->_walkRegions._field18[1]._pt1;
+ *routeList++ = currDestField._pt1;
}
// Mark the end of the path
@@ -746,7 +756,7 @@ int PlayerMover::checkMover(Common::Point &srcPos, const Common::Point &destPos)
return regionIndex;
}
-void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
+void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
Common::Point objPos = _sceneObject->_position;
_sceneObject->_position = srcPos;
uint32 regionBitList = _sceneObject->_regionBitList;
@@ -771,9 +781,10 @@ void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Poin
_sceneObject->_mover = this;
}
-int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
+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];
- v = 0;
+ foundRoute = false;
for (int idx = 0; idx <= *routeList; ++idx)
tempList[idx] = routeList[idx];
@@ -791,24 +802,28 @@ int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
WalkRegion &srcWalkRegion = _globals->_walkRegions[srcRegion];
int distance;
if (!routeList[0]) {
- // No route
+ // The route is empty (new route).
distance = 0;
} else {
+ // Find the distance from the last region in the route.
WalkRegion &region = _globals->_walkRegions[routeList[*routeList]];
distance = findDistance(srcWalkRegion._pt, region._pt);
}
+ // Add the srcRegion to the end of the route.
tempList[++*tempList] = srcRegion;
- int newIndex = *tempList;
+ int ourListSize = *tempList;
if (srcRegion == destRegion) {
- v = 1;
- for (int idx = newIndex; idx <= *tempList; ++idx) {
+ // We made a route to the destination; copy that route and return.
+ foundRoute = true;
+ for (int idx = ourListSize; idx <= *tempList; ++idx) {
routeList[idx] = tempList[idx];
++*routeList;
}
return distance;
} else {
+ // Find the first connected region leading to our destination.
int foundIndex = 0;
int idx = 0;
int currDest;
@@ -821,27 +836,32 @@ int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
++idx;
}
- int resultOffset = 31990;
- while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (v == 0)) {
- int newDistance = proc1(tempList, currDest, destRegion, v);
+ // Check every connected region until we find a route to the destination (or we have no more to check).
+ int bestDistance = 31990;
+ while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (!foundRoute)) {
+ int newDistance = calculateRestOfRoute(tempList, currDest, destRegion, foundRoute);
+
+ if ((newDistance <= bestDistance) || foundRoute) {
+ // We found a shorter possible route, or one leading to the destination.
- if ((newDistance <= resultOffset) || v) {
- routeList[0] = newIndex - 1;
+ // Overwrite the route with this new one.
+ routeList[0] = ourListSize - 1;
- for (int i = newIndex; i <= tempList[0]; ++i) {
+ for (int i = ourListSize; i <= tempList[0]; ++i) {
routeList[i] = tempList[i];
++routeList[0];
}
- resultOffset = newDistance;
+ bestDistance = newDistance;
}
- tempList[0] = newIndex;
+ // Truncate our local list to the size it was before the call.
+ tempList[0] = ourListSize;
++foundIndex;
}
- v = 0;
- return resultOffset + distance;
+ foundRoute = false;
+ return bestDistance + distance;
}
}
@@ -855,71 +875,62 @@ int PlayerMover::findDistance(const Common::Point &pt1, const Common::Point &pt2
return (int)sqrt(xx + yy);
}
-bool PlayerMover::sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
+bool PlayerMover::sub_F8E5_calculatePoint(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
const Common::Point &pt4, Common::Point *ptOut) {
- double diff1 = pt2.x - pt1.x;
- double diff2 = pt2.y - pt1.y;
- double diff3 = pt4.x - pt3.x;
- double diff4 = pt4.y - pt3.y;
- double var10 = 0.0, var8 = 0.0;
- double var18 = 0.0, var20 = 0.0;
+ double diffX1 = pt2.x - pt1.x;
+ double diffY1 = pt2.y - pt1.y;
+ double diffX2 = pt4.x - pt3.x;
+ double diffY2 = pt4.y - pt3.y;
+ double ratio1 = 0.0, ratio2 = 0.0;
+ double adjustedY1 = 0.0, adjustedY2 = 0.0;
- if (diff1 != 0.0) {
- var8 = diff2 / diff1;
- var18 = pt1.y - (pt1.x * var8);
+ // Calculate the ratios between the X and Y points.
+ if (diffX1 != 0.0) {
+ ratio1 = diffY1 / diffX1;
+ adjustedY1 = pt1.y - (pt1.x * ratio1);
}
- if (diff3 != 0.0) {
- var10 = diff4 / diff3;
- var20 = pt3.y - (pt3.x * var10);
+ if (diffX2 != 0.0) {
+ ratio2 = diffY2 / diffX2;
+ adjustedY2 = pt3.y - (pt3.x * ratio2);
}
- if (var8 == var10)
+ if (ratio1 == ratio2)
return false;
- double var48, var50;
- if (diff1 == 0) {
- if (diff3 == 0)
+ double xPos, yPos;
+ if (diffX1 == 0) {
+ if (diffX2 == 0)
return false;
- var48 = pt1.x;
- var50 = var10 * var48 + var20;
+ xPos = pt1.x;
+ yPos = ratio2 * xPos + adjustedY2;
} else {
- var48 = (diff3 == 0) ? pt3.x : (var20 - var18) / (var8 - var10);
- var50 = var8 * var48 + var18;
+ xPos = (diffX2 == 0) ? pt3.x : (adjustedY2 - adjustedY1) / (ratio1 - ratio2);
+ yPos = ratio1 * xPos + adjustedY1;
}
- bool var52 = false, var56 = false, var54 = false, var58 = false;
- Common::Point tempPt((int)(var48 + 0.5), (int)(var50 + 0.5));
-
- if ((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x))
- var56 = true;
- else if ((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x))
- var56 = true;
- if (var56) {
- if ((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y))
- var58 = true;
- else if ((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y))
- var58 = true;
- }
+ // This is our candidate point, which we must check for validity.
+ Common::Point tempPt((int)(xPos + 0.5), (int)(yPos + 0.5));
- if ((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x))
- var52 = true;
- else if ((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x))
- var52 = true;
- if (var52) {
- if ((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y))
- var54 = true;
- else if ((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y))
- var54 = true;
- }
+ // Is tempPt inside the second bounds?
+ if (!((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x)))
+ if (!((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x)))
+ return false;
+ if (!((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y)))
+ if (!((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y)))
+ return false;
- if (var52 && var54 && var56 && var58) {
- if (ptOut)
- *ptOut = tempPt;
- return true;
- }
+ // Is tempPt inside the first bounds?
+ if (!((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x)))
+ if (!((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x)))
+ return false;
+ if (!((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y)))
+ if (!((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y)))
+ return false;
- return false;
+ if (ptOut)
+ *ptOut = tempPt;
+ return true;
}
/*--------------------------------------------------------------------------*/
@@ -2858,8 +2869,6 @@ void Region::draw() {
}
void Region::uniteLine(int yp, LineSliceSet &sliceSet) {
- // TODO: More properly implement like the original
-
// First expand the bounds as necessary to fit in the row
if (_ySlices.empty()) {
_bounds = Rect(sliceSet.items[0].xs, yp, sliceSet.items[sliceSet.items.size() - 1].xe, yp + 1);
@@ -2951,55 +2960,6 @@ int SceneRegions::indexOf(const Common::Point &pt) {
/*--------------------------------------------------------------------------*/
-SoundHandler::SoundHandler() {
- _action = NULL;
- _field280 = -1;
- if (_globals)
- _globals->_sceneListeners.push_back(this);
-}
-
-SoundHandler::~SoundHandler() {
- if (_globals)
- _globals->_sceneListeners.remove(this);
-}
-
-void SoundHandler::dispatch() {
- EventHandler::dispatch();
- int v = _sound.proc12();
-
- if (v != -1) {
- _field280 = v;
- _sound.proc2(-1);
-
- if (_action)
- _action->signal();
- }
-
- if (_field280 != -1) {
- // FIXME: Hardcoded to only flag a sound ended if an action has been set
- if (_action) {
-// if (!_sound.proc3()) {
- _field280 = -1;
- if (_action) {
- _action->signal();
- _action = NULL;
- }
- }
- }
-}
-
-void SoundHandler::startSound(int soundNum, Action *action, int volume) {
- _action = action;
- _field280 = 0;
- setVolume(volume);
- _sound.startSound(soundNum);
-
- warning("TODO: SoundHandler::startSound");
-}
-
-
-/*--------------------------------------------------------------------------*/
-
void SceneItemList::addItems(SceneItem *first, ...) {
va_list va;
va_start(va, first);
@@ -3062,13 +3022,12 @@ void WalkRegion::loadProcessList(byte *dataP, int dataSize, int &dataIndex, int
int yp = READ_LE_UINT16(dataP + idx * 4 + 2);
if (yp != y1) {
/*
- * Commented out: doesn't seem to be used
+ * Commented out: v doesn't seem to be used
int v;
if (idx == (dataSize - 1))
v = READ_LE_UINT16(dataP + 2);
else
v = process1(idx, dataP, dataSize);
- warning("TODO: v not used? - %d", v);
*/
process2(dataIndex, x1, y1, xp, yp);
++dataIndex;
@@ -3480,8 +3439,9 @@ void SceneHandler::postInit(SceneObjectList *OwnerList) {
_globals->_scenePalette.loadPalette(0);
_globals->_scenePalette.refresh();
- // TODO: Bunch of other scene related setup goes here
_globals->_soundManager.postInit();
+ _globals->_soundManager.buildDriverList(true);
+ _globals->_soundManager.installConfigDrivers();
_globals->_game->start();
}
@@ -3584,9 +3544,10 @@ void SceneHandler::dispatch() {
if (_globals->_sceneManager._scene)
_globals->_sceneManager._scene->dispatch();
- //TODO: Figure out purpose of the given list
- //_globals->_regions.forEach(SceneHandler::handleListener);
+ // Not actually used
+ //_eventListeners.forEach(SceneHandler::handleListener);
+ // Handle pending eents
Event event;
while (_globals->_events.getEvent(event))
process(event);
@@ -3610,7 +3571,6 @@ void SceneHandler::dispatchObject(EventHandler *obj) {
}
void SceneHandler::saveListener(Serializer &ser) {
- warning("TODO: SceneHandler::saveListener");
}
} // End of namespace tSage
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index 71130e5b0b..b86e2f63fe 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -33,7 +33,6 @@
#include "tsage/graphics.h"
#include "tsage/resources.h"
#include "tsage/saveload.h"
-#include "tsage/sound.h"
namespace tSage {
@@ -229,12 +228,12 @@ protected:
int regionIndexOf(int xp, int yp) { return regionIndexOf(Common::Point(xp, yp)); }
int findClosestRegion(Common::Point &pt, const Common::List<int> &indexList);
int checkMover(Common::Point &srcPos, const Common::Point &destPos);
- void checkMovement2(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut);
- int proc1(int *routeList, int srcRegion, int destRegion, int &v);
+ void doStepsOfNpcMovement(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut);
+ int calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute);
static Common::Point *findLinePoint(RouteEnds *routeEnds, Common::Point *objPos, int length, Common::Point *outPos);
static int findDistance(const Common::Point &pt1, const Common::Point &pt2);
- static bool sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
+ static bool sub_F8E5_calculatePoint(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
const Common::Point &pt4, Common::Point *ptOut = NULL);
public:
Common::Point _finalDest;
@@ -719,74 +718,6 @@ public:
/*--------------------------------------------------------------------------*/
-class GameSoundHandler {
-public:
- void proc1() {
- warning("TODO: GameSoundHandler::proc1");
- }
- void proc5(int v) {
- warning("TODO: GameSoundHandler::proc5");
- }
- void proc11(int v1, int v2, int v3, int v4) {
- warning("TODO: GameSoundHandler::proc11");
- }
- int proc12() {
- // TODO
- return -1;
- }
- void proc2(int v) {
- // TODO
- }
- int proc3() {
- return 0;
- }
- void setVolume(int volume) {
- warning("TODO GameSoundHandler::setVolume");
- }
- void startSound(int soundNum) {
- warning("TODO GameSoundHandler::startSound");
- }
-};
-
-class SoundHandler : public EventHandler {
-public:
- GameSoundHandler _sound;
- Action *_action;
- int _field280;
-public:
- SoundHandler();
- ~SoundHandler();
-
- void startSound(int soundNum, Action *action = NULL, int volume = 127);
- void proc1(Action *action) {
- proc11(0, 5, 10, 1, action);
- }
- void proc2(int v) {
- warning("TODO: SoundHandler::proc2");
- }
- void proc3() {
- warning("TODO: SoundHandler::proc5");
- }
- void proc4() {
- _sound.proc1();
- }
- void proc5(int v) {
- _sound.proc5(v);
- }
- void proc11(int v1, int v2, int v3, int v4, Action *action) {
- if (action)
- _action = action;
-
- _sound.proc11(v1, v2, v3, v4);
- }
- void setVolume(int volume) { _sound.setVolume(volume); }
-
- virtual Common::String getClassName() { return "SoundHandler"; }
- virtual void dispatch();
-};
-
-/*--------------------------------------------------------------------------*/
-
class SceneItemList : public SynchronizedList<SceneItem *> {
public:
void addItems(SceneItem *first, ...);
diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp
index 5288c98b72..9277fd429a 100644
--- a/engines/tsage/debugger.cpp
+++ b/engines/tsage/debugger.cpp
@@ -63,7 +63,7 @@ bool Debugger::Cmd_Scene(int argc, const char **argv) {
if (argc < 2) {
DebugPrintf("Usage: %s <scene number> [prior scene #]\n", argv[0]);
return true;
- }
+ }
if (argc == 3)
_globals->_sceneManager._sceneNumber = strToInt(argv[2]);
@@ -222,7 +222,7 @@ bool Debugger::Cmd_ListObjects(int argc, const char **argv) {
DebugPrintf("Usage: %s\n", argv[0]);
return true;
}
-
+
DebugPrintf("Available objects for this game are:\n");
DebugPrintf("0 - Stunner\n");
DebugPrintf("1 - Scanner\n");
@@ -393,7 +393,7 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
// Lock the background surface for access
Graphics::Surface destSurface = _globals->_sceneManager._scene->_backSurface.lockSurface();
-
+
// Iterate through the scene items
SynchronizedList<SceneItem *>::iterator i;
for (i = _globals->_sceneItems.reverse_begin(); i != _globals->_sceneItems.end(); --i, ++colIndex) {
@@ -418,7 +418,7 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
LineSliceSet set = r.getLineSlices(y);
for (uint p = 0; p < set.items.size(); ++p)
- destSurface.hLine(set.items[p].xs - sceneBounds.left, y - sceneBounds.top,
+ destSurface.hLine(set.items[p].xs - sceneBounds.left, y - sceneBounds.top,
set.items[p].xe - sceneBounds.left - 1, colIndex);
}
}
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index 20c2002257..aaa9030a04 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -66,25 +66,16 @@ static const PlainGameDescriptor tSageGameTitles[] = {
#include "engines/tsage/detection_tables.h"
-static const ADParams detectionParams = {
- (const byte *)tSage::gameDescriptions,
- sizeof(tSage::tSageGameDescription),
- 0,
- tSageGameTitles,
- 0,
- "tsage",
- NULL,
- 0,
- Common::GUIO_NONE,
- 0,
- NULL
+enum {
+ MAX_SAVES = 100
};
-#define MAX_SAVES 100
-
class TSageMetaEngine : public AdvancedMetaEngine {
public:
- TSageMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TSageMetaEngine() : AdvancedMetaEngine(tSage::gameDescriptions, sizeof(tSage::tSageGameDescription), tSageGameTitles) {
+ _md5Bytes = 5000;
+ _singleid = "tsage";
+ _guioptions = Common::GUIO_NOSPEECH;
}
virtual const char *getName() const {
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index dc55f2a66d..8b80edf89d 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -24,7 +24,7 @@ namespace tSage {
static const tSageGameDescription gameDescriptions[] = {
- // Ringworld English CD version
+ // Ringworld CD and First Wave versions
{
{
"ring",
@@ -32,22 +32,8 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("ring.rlb", "466f0e6492d9d0f34d35c5cd088de90f", 37847618),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
- Common::GUIO_NONE
- },
- GType_Ringworld,
- GF_CD | GF_ALT_REGIONS
- },
- // Ringworld First Wave English CD version
- {
- {
- "ring",
- "CD",
- AD_ENTRY1s("ring.rlb", "0a25b4ee58d44a54425c0b47e5096bbc", 37847618),
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ ADGF_UNSTABLE,
+ Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_Ringworld,
GF_CD | GF_ALT_REGIONS
@@ -57,11 +43,11 @@ static const tSageGameDescription gameDescriptions[] = {
{
"ring",
"Floppy",
- AD_ENTRY1s("ring.rlb", "61f78f68a56832ae95fe06748c403234", 8438770),
+ AD_ENTRY1s("ring.rlb", "7b7f0c5b37b58fa5ec06ebb2ca0d0d9d", 8438770),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ ADGF_UNSTABLE,
+ Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_Ringworld,
GF_FLOPPY
@@ -71,54 +57,57 @@ static const tSageGameDescription gameDescriptions[] = {
{
"ring",
"Floppy Demo",
- AD_ENTRY1s("tsage.rlb", "bf4e8525d0cab84b08b57126092eeacd", 833453),
+ AD_ENTRY1s("tsage.rlb", "3b3604a97c06c91f3735d3e9d341f63f", 833453),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- Common::GUIO_NONE
+ Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_Ringworld,
GF_FLOPPY | GF_DEMO
},
+
// Ringworld English Floppy Demo #2 version
{
{
"ring",
"Floppy Demo",
- AD_ENTRY1s("demoring.rlb", "9ecf48e088a0d475778fab480b3dbdd0", 832206),
+ AD_ENTRY1s("demoring.rlb", "64050e1806203b15bb03876140eb4f56", 832206),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- Common::GUIO_NONE
+ Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_Ringworld,
GF_FLOPPY | GF_DEMO | GF_ALT_REGIONS
},
-
- // Blue Force
+#if 0
+ // FIXME: Compute new MD5s based on 5000 bytes instead of 0 (unlimited)
+ // Blue Force floppy
{
{
"blueforce",
- "",
- AD_ENTRY1s("blue.rlb", "467da43c848cc0e800b547c59d84ccb1", 10032614),
+ "Floppy",
+ AD_ENTRY1s("blue.rlb", "17c3993415e8a2cf93040eef7e88ec93", 1156508),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ ADGF_UNSTABLE,
+ Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_BlueForce,
GF_FLOPPY
},
- // Blue Force floppy
+#endif
+ // Blue Force
{
{
"blueforce",
- "Floppy",
- AD_ENTRY1s("blue.rlb", "17c3993415e8a2cf93040eef7e88ec93", 1156508),
+ "",
+ AD_ENTRY1s("blue.rlb", "17eabb456cb1546c66baf1aff387ba6a", 10032614),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_BlueForce,
GF_FLOPPY
@@ -128,11 +117,11 @@ static const tSageGameDescription gameDescriptions[] = {
{
"blueforce",
"CD",
- AD_ENTRY1s("blue.rlb", "ac29f38184cb3b874ea18523059872ba", 63863322),
+ AD_ENTRY1s("blue.rlb", "99983f48cb218f1f3760cf2f9a7ef11d", 63863322),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_BlueForce,
GF_CD
diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp
index c1bd1d027f..86fbbc8e43 100644
--- a/engines/tsage/dialogs.cpp
+++ b/engines/tsage/dialogs.cpp
@@ -43,7 +43,7 @@ MessageDialog::MessageDialog(const Common::String &message, const Common::String
const Common::String &btn2Message) : GfxDialog() {
// Set up the message
addElements(&_msg, &_btn1, NULL);
-
+
_msg.set(message, 200, ALIGN_LEFT);
_msg._bounds.moveTo(0, 0);
_defaultButton = &_btn1;
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 9df2a7ccd6..a24f65421b 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -48,6 +48,7 @@ bool EventsClass::pollEvent() {
_priorFrameTime = milli;
++_frameNumber;
+ // Update screen
g_system->updateScreen();
}
@@ -280,7 +281,7 @@ void EventsClass::hideCursor() {
setCursor(CURSOR_NONE);
}
-bool EventsClass::isCursorVisible() const {
+bool EventsClass::isCursorVisible() const {
return !_globals->getFlag(122);
}
@@ -307,7 +308,7 @@ void EventsClass::delay(int numFrames) {
void EventsClass::listenerSynchronize(Serializer &s) {
s.syncAsUint32LE(_frameNumber);
s.syncAsUint32LE(_prevDelayFrame);
-
+
if (s.getVersion() >= 5) {
s.syncAsSint16LE(_currentCursor);
s.syncAsSint16LE(_lastCursor);
diff --git a/engines/tsage/events.h b/engines/tsage/events.h
index a13455d378..e0fbd88745 100644
--- a/engines/tsage/events.h
+++ b/engines/tsage/events.h
@@ -37,6 +37,7 @@ enum EventType {EVENT_NONE = 0, EVENT_BUTTON_DOWN = 1, EVENT_BUTTON_UP = 2, EVEN
enum ButtonShiftFlags {BTNSHIFT_LEFT = 0, BTNSHIFT_RIGHT = 3, BTNSHIFT_MIDDLE = 4};
// Intrinisc game delay between execution frames. This runs at 60Hz
+#define GAME_FRAME_RATE 60
#define GAME_FRAME_TIME (1000 / 60)
class GfxManager;
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 863f1458b1..34b26ec311 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -94,8 +94,8 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_sceneObjects_queue.push_front(_sceneObjects);
_prevSceneOffset = Common::Point(-1, -1);
- _sceneListeners.push_back(&_soundHandler);
- _sceneListeners.push_back(&_sequenceManager._soundHandler);
+ _sounds.push_back(&_soundHandler);
+ _sounds.push_back(&_sequenceManager._soundHandler);
_scrollFollower = NULL;
_inventory = NULL;
@@ -117,9 +117,9 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
}
Globals::~Globals() {
- _globals = NULL;
delete _inventory;
delete _game;
+ _globals = NULL;
}
void Globals::reset() {
@@ -140,7 +140,7 @@ void Globals::synchronize(Serializer &s) {
s.syncAsSint32LE(_gfxColors.foreground);
s.syncAsSint32LE(_fontColors.background);
s.syncAsSint32LE(_fontColors.foreground);
-
+
if (s.getVersion() >= 4) {
s.syncAsByte(_unkColor1);
s.syncAsByte(_unkColor2);
@@ -148,7 +148,7 @@ void Globals::synchronize(Serializer &s) {
}
s.syncAsSint16LE(_dialogCenter.x); s.syncAsSint16LE(_dialogCenter.y);
- _sceneListeners.synchronize(s);
+ _sounds.synchronize(s);
for (int i = 0; i < 256; ++i)
s.syncAsByte(_flags[i]);
@@ -158,4 +158,13 @@ void Globals::synchronize(Serializer &s) {
s.syncAsSint32LE(_stripNum);
}
+void Globals::dispatchSound(ASound *obj) {
+ obj->dispatch();
+}
+
+void Globals::dispatchSounds() {
+ Common::for_each(_sounds.begin(), _sounds.end(), Globals::dispatchSound);
+}
+
+
} // end of namespace tSage
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index 8212387ed1..7cfec718e2 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -28,11 +28,14 @@
#include "tsage/dialogs.h"
#include "tsage/scenes.h"
#include "tsage/events.h"
+#include "tsage/sound.h"
#include "tsage/saveload.h"
namespace tSage {
class Globals : public SavedObject {
+private:
+ static void dispatchSound(ASound *obj);
public:
GfxSurface _screenSurface;
GfxManager _gfxManagerInstance;
@@ -55,10 +58,10 @@ public:
SoundManager _soundManager;
Common::Point _dialogCenter;
WalkRegions _walkRegions;
- SynchronizedList<EventHandler *> _sceneListeners;
+ SynchronizedList<ASound *> _sounds;
bool _flags[256];
Player _player;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
InvObjectList *_inventory;
Region _paneRegions[2];
int _paneRefreshFlag[2];
@@ -90,6 +93,7 @@ public:
GfxManager &gfxManager() { return **_gfxManagers.begin(); }
virtual Common::String getClassName() { return "Globals"; }
virtual void synchronize(Serializer &s);
+ void dispatchSounds();
};
extern Globals *_globals;
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index 25dc897ecd..fce9e1317d 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -326,7 +326,7 @@ void GfxSurface::synchronize(Serializer &s) {
s.syncAsSint16LE(zero);
}
} else {
- int w, h;
+ int w = 0, h = 0;
s.syncAsSint16LE(w);
s.syncAsSint16LE(h);
@@ -846,7 +846,7 @@ void GfxButton::setDefaults() {
gfxManager._font.getStringBounds(_message.c_str(), tempRect, 240);
tempRect.right = ((tempRect.right + 15) / 16) * 16;
- // Set the button bounds
+ // Set the button bounds
tempRect.collapse(-_globals->_gfxEdgeAdjust, -_globals->_gfxEdgeAdjust);
if (_vm->getFeatures() & GF_CD)
--tempRect.top;
@@ -866,7 +866,7 @@ void GfxButton::draw() {
// Set the font and color
gfxManager._font.setFontNumber(_fontNumber);
- //
+ //
gfxManager._font._colors.foreground = this->_unkColor1;
gfxManager._font._colors2.background = this->_unkColor2;
gfxManager._font._colors2.foreground = this->_unkColor3;
@@ -895,7 +895,7 @@ bool GfxButton::process(Event &event) {
case EVENT_KEYPRESS:
if (!event.handled && (event.kbd.keycode == _keycode)) {
- // TODO: Ensure momentary click operation displays
+ // Highlight the button momentarily
highlight();
g_system->delayMillis(20);
highlight();
diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp
index 676d319ba9..6d2c6b5837 100644
--- a/engines/tsage/resources.cpp
+++ b/engines/tsage/resources.cpp
@@ -66,7 +66,9 @@ uint16 MemoryManager::allocate(uint32 size) {
byte *MemoryManager::allocate2(uint32 size) {
uint32 idx = allocate(size);
- return lock(idx);
+ byte *result = lock(idx);
+ Common::set_to(result, result + size, 0);
+ return result;
}
byte *MemoryManager::lock(uint32 handle) {
@@ -235,8 +237,13 @@ byte *TLib::getResource(uint16 id, bool suppressErrors) {
uint16 ctrCurrent = 0x102, ctrMax = 0x200;
uint16 word_48050 = 0, currentToken = 0, word_48054 =0;
byte byte_49068 = 0, byte_49069 = 0;
- DecodeReference table[0x1000];
- for (int i = 0; i < 0x1000; ++i) {
+
+ const uint tableSize = 0x1000;
+ DecodeReference *table = (DecodeReference *)malloc(tableSize * sizeof(DecodeReference));
+ if (!table)
+ error("[TLib::getResource] Cannot allocate table buffer");
+
+ for (uint i = 0; i < tableSize; ++i) {
table[i].vByte = table[i].vWord = 0;
}
Common::Stack<uint16> tokenList;
@@ -300,6 +307,8 @@ byte *TLib::getResource(uint16 id, bool suppressErrors) {
}
}
+ free(table);
+
assert(bytesWritten == re->uncompressedSize);
delete compStream;
return dataOut;
diff --git a/engines/tsage/ringworld_demo.cpp b/engines/tsage/ringworld_demo.cpp
index de8dbf8c12..b24fec98f9 100644
--- a/engines/tsage/ringworld_demo.cpp
+++ b/engines/tsage/ringworld_demo.cpp
@@ -30,7 +30,7 @@ namespace tSage {
void RingworldDemoGame::start() {
// Start the demo's single scene
_globals->_sceneManager.changeScene(1);
-
+
_globals->_events.setCursor(CURSOR_NONE);
}
@@ -72,6 +72,7 @@ void RingworldDemoGame::processEvent(Event &event) {
ConfigDialog *dlg = new ConfigDialog();
dlg->runModal();
delete dlg;
+ _globals->_soundManager.syncSounds();
_globals->_events.setCursorFromFlag();
break;
}
@@ -101,19 +102,19 @@ void RingworldDemoScene::postInit(SceneObjectList *OwnerList) {
}
void RingworldDemoScene::signal() {
- _soundHandler.startSound(4);
+ _soundHandler.play(4);
_actor1.postInit();
_actor2.postInit();
_actor3.postInit();
_actor4.postInit();
_actor5.postInit();
_actor6.postInit();
-
+
setAction(&_sequenceManager, this, 22, &_actor1, &_actor2, &_actor3, &_actor4, &_actor5, &_actor6, NULL);
}
void RingworldDemoScene::process(Event &event) {
-
+
}
} // End of namespace tSage
diff --git a/engines/tsage/ringworld_demo.h b/engines/tsage/ringworld_demo.h
index 7492c1e871..3e7431e107 100644
--- a/engines/tsage/ringworld_demo.h
+++ b/engines/tsage/ringworld_demo.h
@@ -28,6 +28,7 @@
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
+#include "tsage/sound.h"
namespace tSage {
@@ -46,7 +47,7 @@ public:
SequenceManager _sequenceManager;
SceneObject _actor1, _actor2, _actor3;
SceneObject _actor4, _actor5, _actor6;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void process(Event &event);
diff --git a/engines/tsage/ringworld_logic.cpp b/engines/tsage/ringworld_logic.cpp
index 95c9da9fe7..58501172af 100644
--- a/engines/tsage/ringworld_logic.cpp
+++ b/engines/tsage/ringworld_logic.cpp
@@ -268,7 +268,7 @@ void SceneArea::setup(int resNum, int rlbNum, int subNum, int actionId) {
}
void SceneArea::draw2() {
- _surface.draw(Common::Point(_bounds.left, _bounds.top));
+ _surface.draw(Common::Point(_bounds.left, _bounds.top));
}
void SceneArea::display() {
@@ -619,7 +619,7 @@ void SpeakerSKL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(203, 120));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(7013);
_object2.setStrip2(1);
@@ -651,7 +651,7 @@ void SpeakerQL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(128, 146));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(2612);
_object2.setStrip2(1);
@@ -667,7 +667,6 @@ void SpeakerQL::setText(const Common::String &msg) {
/*--------------------------------------------------------------------------*/
SpeakerSR::SpeakerSR() {
- // TODO: check initialization of object3
_speakerName = "SR";
_newSceneNumber = 2811;
_textPos = Common::Point(10, 30);
@@ -684,7 +683,7 @@ void SpeakerSR::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(224, 198));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(2813);
_object2.setStrip2(1);
@@ -725,7 +724,7 @@ void SpeakerSL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(95, 198));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(2812);
_object2.setStrip2(1);
@@ -757,7 +756,7 @@ void SpeakerQR::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(191, 146));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(2613);
_object2.setStrip2(1);
@@ -789,7 +788,7 @@ void SpeakerQU::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(116, 120));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(7021);
_object2.setStrip2(1);
@@ -818,7 +817,7 @@ void SpeakerCR::setText(const Common::String &msg) {
_object1.fixPriority(255);
_object1.setPosition(Common::Point(219, 168));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(9011);
_object2.setStrip2(1);
@@ -847,7 +846,7 @@ void SpeakerMR::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(220, 143));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(2713);
_object2.setStrip2(1);
@@ -879,7 +878,7 @@ void SpeakerSAL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(185, 200));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(2853);
_object2.setStrip2(1);
@@ -910,7 +909,7 @@ void SpeakerML::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(99, 143));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(2712);
_object2.setStrip2(1);
@@ -941,7 +940,7 @@ void SpeakerCHFL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(205, 116));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(4113);
_object2.setStrip2(1);
@@ -972,7 +971,7 @@ void SpeakerCHFR::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(103, 116));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(4112);
_object2.setStrip2(1);
@@ -1003,7 +1002,7 @@ void SpeakerPL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(107, 117));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(4062);
_object2.setStrip2(1);
@@ -1048,7 +1047,7 @@ void SpeakerPR::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(212, 117));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(4063);
_object2.setStrip2(2);
@@ -1093,7 +1092,7 @@ void SpeakerCDR::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(208, 97));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(4163);
_object2.setStrip2(2);
@@ -1124,7 +1123,7 @@ void SpeakerCDL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(112, 97));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(4162);
_object2.setStrip2(2);
@@ -1155,7 +1154,7 @@ void SpeakerFLL::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(216, 129));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(5223);
_object2.setStrip2(1);
@@ -1186,7 +1185,7 @@ void SpeakerBatR::setText(const Common::String &msg) {
_object1._frame = 1;
_object1.setPosition(Common::Point(137, 122));
_object1.animate(ANIM_MODE_7, 0, NULL);
-
+
_object2.postInit(&_objectList);
_object2.setVisage(5361);
_object2.setStrip2(1);
@@ -1334,9 +1333,20 @@ void RingworldGame::start() {
RING_INVENTORY._scanner._sceneNumber = 1;
RING_INVENTORY._ring._sceneNumber = 1;
+ int slot = -1;
+
+ if (ConfMan.hasKey("save_slot")) {
+ slot = ConfMan.getInt("save_slot");
+ Common::String file = _vm->generateSaveName(slot);
+ Common::InSaveFile *in = _vm->_system->getSavefileManager()->openForLoading(file);
+ if (in)
+ delete in;
+ else
+ slot = -1;
+ }
- if (ConfMan.hasKey("save_slot"))
- _globals->_sceneHandler._loadGameSlot = ConfMan.getInt("save_slot");
+ if (slot >= 0)
+ _globals->_sceneHandler._loadGameSlot = slot;
else
// Switch to the title screen
_globals->_sceneManager.setNewScene(1000);
@@ -1346,7 +1356,7 @@ void RingworldGame::start() {
void RingworldGame::restart() {
_globals->_scenePalette.clearListeners();
- _globals->_soundHandler.proc3();
+ _globals->_soundHandler.stop();
// Reset the flags
_globals->reset();
@@ -1441,6 +1451,7 @@ void RingworldGame::processEvent(Event &event) {
ConfigDialog *dlg = new ConfigDialog();
dlg->runModal();
delete dlg;
+ _globals->_soundManager.syncSounds();
_globals->_events.setCursorFromFlag();
break;
}
diff --git a/engines/tsage/ringworld_scenes1.cpp b/engines/tsage/ringworld_scenes1.cpp
index 6960788db3..7fe2610fd7 100644
--- a/engines/tsage/ringworld_scenes1.cpp
+++ b/engines/tsage/ringworld_scenes1.cpp
@@ -98,7 +98,7 @@ void Scene10::Action1::signal() {
scene->_object4.animate(ANIM_MODE_6, this);
break;
case 10:
- _globals->_soundHandler.proc1(this);
+ _globals->_soundHandler.fadeOut(this);
break;
case 11:
_globals->_scenePalette.clearListeners();
@@ -185,7 +185,7 @@ void Scene10::postInit(SceneObjectList *OwnerList) {
_globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
setAction(&_action1);
- _globals->_soundHandler.startSound(5);
+ _globals->_soundHandler.play(5);
}
void Scene10::stripCallback(int v) {
@@ -232,7 +232,7 @@ void Scene15::Action1::signal() {
Common::Point pt(160, 100);
NpcMover *mover = new NpcMover();
scene->_object1.addMover(mover, &pt, this);
- scene->_soundHandler.startSound(7);
+ scene->_soundHandler.play(7);
break;
}
case 3:
@@ -256,7 +256,7 @@ void Scene15::postInit(SceneObjectList *OwnerList) {
loadScene(15);
Scene::postInit();
setZoomPercents(0, 100, 200, 100);
- _globals->_soundHandler.startSound(6);
+ _globals->_soundHandler.play(6);
setAction(&_action1);
}
@@ -276,7 +276,7 @@ void Scene20::Action1::signal() {
scene->_stripManager.start(20, this);
break;
case 2:
- _globals->_soundHandler.proc1(this);
+ _globals->_soundHandler.fadeOut(this);
break;
case 3:
_globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
@@ -341,8 +341,8 @@ void Scene20::Action2::signal() {
break;
}
case 8:
- scene->_sound.proc4();
- scene->_sound.proc1(this);
+ scene->_sound.release();
+ _globals->_soundHandler.fadeOut(this);
break;
case 9:
SceneItem::display(0, 0, LIST_END);
@@ -400,8 +400,8 @@ void Scene20::Action3::signal() {
break;
}
case 6:
- scene->_sound.startSound(60, this, 127);
- _globals->_soundHandler.proc4();
+ scene->_sound.play(60, this, 127);
+ _globals->_soundHandler.release();
break;
case 7:
_globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
@@ -450,7 +450,7 @@ void Scene20::Action4::signal() {
break;
}
case 4: {
- scene->_sound.startSound(28);
+ scene->_sound.play(28);
scene->_sceneObject4.postInit();
scene->_sceneObject4.setVisage(21);
scene->_sceneObject4.setStrip(3);
@@ -463,7 +463,7 @@ void Scene20::Action4::signal() {
break;
}
case 5: {
- scene->_sound.startSound(42);
+ scene->_sound.play(42);
scene->_sceneObject4.remove();
scene->_SceneObjectExt.setVisage(21);
scene->_SceneObjectExt.setStrip(1);
@@ -487,7 +487,7 @@ void Scene20::Action4::signal() {
break;
}
case 6: {
- scene->_sound.startSound(42);
+ scene->_sound.play(42);
scene->_SceneObjectExt.setStrip(2);
scene->_SceneObjectExt.animate(ANIM_MODE_2, NULL);
@@ -506,7 +506,7 @@ void Scene20::Action4::signal() {
case 7:
_globals->_player.setStrip(2);
_globals->_player.animate(ANIM_MODE_2, NULL);
- scene->_sound.startSound(77, this, 127);
+ scene->_sound.play(77, this, 127);
break;
case 8:
_globals->_game->endGame(20, 0);
@@ -549,15 +549,15 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
_SceneObjectExt._moveDiff = Common::Point(10, 10);
_sceneObject3._moveDiff = Common::Point(10, 10);
- _globals->_soundHandler.startSound(20);
- _sound.startSound(21);
- _sound.proc5(1);
+ _globals->_soundHandler.play(20);
+ _sound.play(21);
+ _sound.holdAt(true);
setAction(&_action2);
_sceneBounds = Rect(320, 0, 640, 200);
} else if (_globals->_sceneManager._previousScene == 60) {
// Evasion
- _sound.startSound(30);
+ _sound.play(30);
_globals->_player.postInit();
_globals->_player.setVisage(20);
_globals->_player.setPosition(Common::Point(588, 79));
@@ -605,7 +605,7 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
_speakerGameText.setTextPos(Common::Point(350, 20));
_speakerGameText._textWidth = 260;
- _globals->_soundHandler.startSound(8);
+ _globals->_soundHandler.play(8);
_sceneBounds = Rect(320, 0, 640, 200);
}
@@ -669,7 +669,7 @@ void Scene30::BeamAction::signal() {
case 2:
// Hide the beam and lower the player's hand
- scene->_sound.startSound(10, NULL, 127);
+ scene->_sound.play(10, NULL, 127);
_globals->_player.animate(ANIM_MODE_6, this);
scene->_beam.remove();
break;
@@ -693,14 +693,14 @@ void Scene30::BeamAction::signal() {
case 4:
// Open the door
- scene->_sound.startSound(11, NULL, 127);
+ scene->_sound.play(11, NULL, 127);
scene->_door.animate(ANIM_MODE_5, this);
break;
case 5:
// Run the Kzin's talk sequence
- scene->_sound.startSound(13, NULL, 127);
- _globals->_soundHandler.startSound(12, NULL, 127);
+ scene->_sound.play(13, NULL, 127);
+ _globals->_soundHandler.play(12, NULL, 127);
scene->_stripManager.start((scene->_sceneMode == 0) ? 30 : 37, this);
break;
@@ -732,7 +732,7 @@ void Scene30::KzinAction::signal() {
setDelay(1200);
break;
case 1:
- _globals->_soundHandler.proc2(0);
+ _globals->_soundHandler.fadeOut(NULL);
_globals->_player.disableControl();
setAction(&scene->_sequenceManager, _globals->_sceneManager._scene, 31, &scene->_kzin, &scene->_door, NULL);
break;
@@ -772,12 +772,12 @@ void Scene30::RingAction::signal() {
}
case 3:
- scene->_sound.startSound(11, NULL, 127);
+ scene->_sound.play(11, NULL, 127);
scene->_door.animate(ANIM_MODE_6, this);
break;
case 4: {
- scene->_sound.startSound(13, NULL, 127);
+ scene->_sound.play(13, NULL, 127);
NpcMover *kzinMover = new NpcMover();
Common::Point pt(354, 5);
scene->_kzin.addMover(kzinMover, &pt, this);
@@ -955,7 +955,7 @@ void Scene40::Action1::signal() {
scene->_doorway.setVisage(46);
scene->_doorway.setPosition(Common::Point(305, 61));
scene->_doorway.animate(ANIM_MODE_5, this);
- scene->_soundHandler.startSound(25);
+ scene->_soundHandler.play(25);
break;
case 3:
scene->_doorway.hide();
@@ -976,7 +976,7 @@ void Scene40::Action1::signal() {
scene->_assassin.setFrame(1);
scene->_assassin.setPosition(Common::Point(13, 171));
scene->_assassin.animate(ANIM_MODE_5, this);
- scene->_soundHandler.startSound(25);
+ scene->_soundHandler.play(25);
break;
case 5:
scene->_doorway.show();
@@ -1011,7 +1011,7 @@ void Scene40::Action1::signal() {
break;
}
case 10: {
- scene->_soundHandler.startSound(27);
+ scene->_soundHandler.play(27);
Common::Point pt(223, 184);
NpcMover *mover = new NpcMover();
scene->_dyingKzin.addMover(mover, &pt, this);
@@ -1024,7 +1024,7 @@ void Scene40::Action1::signal() {
break;
}
case 12: {
- _globals->_soundHandler.startSound(26);
+ _globals->_soundHandler.play(26);
_globals->_player._uiEnabled = true;
scene->_assassin.setVisage(42);
scene->_assassin.setPosition(Common::Point(4, 191));
@@ -1043,7 +1043,7 @@ void Scene40::Action1::signal() {
scene->_assassin.setStrip(1);
scene->_assassin.setFrame(1);
scene->_assassin.animate(ANIM_MODE_5, this);
- scene->_soundHandler.startSound(28);
+ scene->_soundHandler.play(28);
break;
case 15:
_globals->_player.disableControl();
@@ -1057,7 +1057,7 @@ void Scene40::Action1::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 16:
- _globals->_soundHandler.startSound(77, this);
+ _globals->_soundHandler.play(77, this);
break;
case 17:
_globals->_game->endGame(40, 20);
@@ -1083,7 +1083,7 @@ void Scene40::Action2::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 2: {
- scene->_soundHandler.startSound(28);
+ scene->_soundHandler.play(28);
scene->_doorway.postInit();
scene->_doorway.setVisage(16);
scene->_doorway.setStrip2(6);
@@ -1103,7 +1103,7 @@ void Scene40::Action2::signal() {
scene->_assassin.setVisage(44);
scene->_assassin._frame = 1;
scene->_assassin.animate(ANIM_MODE_5, this);
- scene->_soundHandler.startSound(29);
+ scene->_soundHandler.play(29);
RING_INVENTORY._infoDisk._sceneNumber = 40;
break;
case 4:
@@ -1234,11 +1234,11 @@ void Scene40::Action6::signal() {
scene->_doorway.setVisage(46);
scene->_doorway.setPosition(Common::Point(305, 61));
scene->_doorway.animate(ANIM_MODE_5, this);
- scene->_soundHandler.startSound(25);
+ scene->_soundHandler.play(25);
break;
}
case 1:
- scene->_soundHandler.startSound(28);
+ scene->_soundHandler.play(28);
scene->_doorway.setPosition(Common::Point(148, 74));
scene->_doorway.setFrame(1);
scene->_doorway.setStrip(2);
@@ -1255,8 +1255,7 @@ void Scene40::Action7::signal() {
switch (_actionIndex++) {
case 0:
- // TODO: check if it's rand(500) or rand(499)+500
- setDelay(_globals->_randomSource.getRandomNumber(500));
+ setDelay(_globals->_randomSource.getRandomNumber(499) + 500);
break;
case 1:
scene->_object7.postInit();
@@ -1270,7 +1269,7 @@ void Scene40::Action7::signal() {
scene->_object7.setFrame(15);
}
scene->_object7.animate(ANIM_MODE_5, this);
- scene->_soundHandler.startSound(25);
+ scene->_soundHandler.play(25);
break;
case 2:
scene->_object7.remove();
@@ -1322,7 +1321,7 @@ void Scene40::Action8::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 3:
- _globals->_soundHandler.startSound(77, this);
+ _globals->_soundHandler.play(77, this);
break;
case 4:
_globals->_game->endGame(40, 45);
@@ -1480,7 +1479,7 @@ void Scene40::postInit(SceneObjectList *OwnerList) {
_globals->_player.disableControl();
if (_globals->_sceneManager._previousScene == 20) {
- _globals->_soundHandler.startSound(24);
+ _globals->_soundHandler.play(24);
_globals->_player.setVisage(43);
_object1.postInit();
@@ -1872,7 +1871,7 @@ void Scene60::Action1::signal() {
scene->_floppyDrive.setPosition(Common::Point(136, 65));
scene->_floppyDrive.animate(ANIM_MODE_5, this);
- scene->_soundHandler1.startSound(35);
+ scene->_soundHandler1.play(35);
break;
case 2:
scene->_redLights.postInit();
@@ -1893,13 +1892,13 @@ void Scene60::Action1::signal() {
scene->_message._numFrames = 5;
_globals->_sceneItems.push_front(&scene->_message);
- scene->_soundHandler2.startSound(38);
+ scene->_soundHandler2.play(38);
}
_globals->_events.setCursor(CURSOR_USE);
break;
case 3:
- scene->_soundHandler2.startSound(37);
+ scene->_soundHandler2.play(37);
scene->loadScene(65);
scene->_message.remove();
@@ -1968,8 +1967,8 @@ void Scene60::Action1::signal() {
scene->_floppyDrive.setFrame(scene->_floppyDrive.getFrameCount());
scene->_floppyDrive.animate(ANIM_MODE_6, this);
- scene->_soundHandler1.startSound(35);
- scene->_soundHandler3.proc3();
+ scene->_soundHandler1.play(35);
+ scene->_soundHandler3.stop();
scene->_masterButton.setFrame(1);
scene->_masterButton._state = 0;
@@ -2019,7 +2018,7 @@ void Scene60::PrevObject::doAction(int action) {
animate(ANIM_MODE_8, 1, NULL);
if (scene->_action1.getActionIndex() > 5) {
- scene->_soundHandler3.startSound(36);
+ scene->_soundHandler3.play(36);
scene->_action1.setActionIndex(scene->_action1.getActionIndex() - 2);
scene->_action1.setDelay(1);
}
@@ -2037,7 +2036,7 @@ void Scene60::NextObject::doAction(int action) {
animate(ANIM_MODE_8, 1, NULL);
if (scene->_action1.getActionIndex() < 8) {
- scene->_soundHandler3.startSound(36);
+ scene->_soundHandler3.play(36);
scene->_action1.setDelay(1);
}
} else {
@@ -2051,7 +2050,7 @@ void Scene60::ExitObject::doAction(int action) {
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 18);
} else if (action == CURSOR_USE) {
- scene->_soundHandler3.startSound(36);
+ scene->_soundHandler3.play(36);
animate(ANIM_MODE_8, 1, NULL);
scene->_nextButton.remove();
scene->_prevButton.remove();
@@ -2132,8 +2131,8 @@ void Scene60::ControlObject::doAction(int action) {
if (_animateMode == ANIM_MODE_NONE)
SceneItem::display2(60, 14);
else if (!scene->_slaveButton._state) {
- _globals->_soundHandler.startSound(40);
- _globals->_soundHandler.proc5(1);
+ _globals->_soundHandler.play(40);
+ _globals->_soundHandler.holdAt(true);
_globals->_sceneManager.changeScene(20);
} else {
scene->_sceneMode = 15;
@@ -2153,14 +2152,14 @@ void Scene60::SlaveObject::doAction(int action) {
if (scene->_masterButton._state)
scene->_sceneMode = 19;
else if (_state) {
- scene->_soundHandler3.proc3();
+ scene->_soundHandler3.stop();
animate(ANIM_MODE_6, NULL);
_globals->clearFlag(102);
_globals->clearFlag(!_globals->_stripNum ? 117 : 120);
_state = 0;
scene->_sceneMode = 9998;
} else {
- scene->_soundHandler3.startSound(39);
+ scene->_soundHandler3.play(39);
_globals->setFlag(102);
_globals->setFlag(!_globals->_stripNum ? 117 : 120);
animate(ANIM_MODE_5, NULL);
@@ -2185,14 +2184,14 @@ void Scene60::MasterObject::doAction(int action) {
else if (scene->_slaveButton._state)
scene->_sceneMode = 20;
else if (_state) {
- scene->_soundHandler3.proc3();
+ scene->_soundHandler3.stop();
animate(ANIM_MODE_6, NULL);
_state = 0;
_globals->clearFlag(103);
_globals->clearFlag(!_globals->_stripNum ? 116 : 119);
scene->_sceneMode = 9998;
} else {
- scene->_soundHandler3.startSound(39);
+ scene->_soundHandler3.play(39);
animate(ANIM_MODE_5, NULL);
_state = 1;
_globals->setFlag(103);
@@ -2347,7 +2346,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
_redLights.setPosition(Common::Point(199, 186));
_redLights.animate(ANIM_MODE_8, 0, NULL);
- _soundHandler1.startSound(35);
+ _soundHandler1.play(35);
if (!_globals->getFlag(83)) {
_message.postInit();
@@ -2359,7 +2358,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
_message._numFrames = 5;
_globals->_sceneItems.push_front(&_message);
- _soundHandler2.startSound(38);
+ _soundHandler2.play(38);
}
}
} else {
@@ -2382,7 +2381,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
_redLights.animate(ANIM_MODE_8, 0, NULL);
_redLights._numFrames = 5;
- _soundHandler1.startSound(35);
+ _soundHandler1.play(35);
if (!_globals->getFlag(83)) {
_message.postInit();
@@ -2394,7 +2393,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
_message._numFrames = 5;
_globals->_sceneItems.push_front(&_message);
- _soundHandler2.startSound(38);
+ _soundHandler2.play(38);
}
}
}
@@ -2462,7 +2461,7 @@ void Scene90::Action1::signal() {
setDelay(2);
break;
case 5:
- scene->_soundHandler2.startSound(58);
+ scene->_soundHandler2.play(58);
if (scene->_stripManager._field2E8 == 220)
scene->_stripManager.start(91, this, scene);
@@ -2477,7 +2476,7 @@ void Scene90::Action1::signal() {
break;
case 7:
scene->_object2.animate(ANIM_MODE_NONE);
- _globals->_soundHandler.startSound(56);
+ _globals->_soundHandler.play(56);
scene->_object3.animate(ANIM_MODE_5, this);
break;
case 8: {
@@ -2507,8 +2506,8 @@ void Scene90::Action1::signal() {
break;
}
case 11:
- _globals->_soundHandler.startSound(57);
- _globals->_soundHandler.startSound(68);
+ _globals->_soundHandler.play(57);
+ _globals->_soundHandler.play(68);
scene->_object3.animate(ANIM_MODE_6, NULL);
SceneItem::display(90, _globals->getFlag(104) ? 15 : 14,
@@ -2556,8 +2555,8 @@ void Scene90::Object2::doAction(int action) {
scene->_object6.hide();
scene->_sceneMode = 91;
- scene->_soundHandler1.startSound(59);
- scene->_soundHandler1.proc5(1);
+ scene->_soundHandler1.play(59);
+ scene->_soundHandler1.holdAt(true);
scene->setAction(&scene->_sequenceManager, scene, 91, this, &scene->_object6, NULL);
break;
case CURSOR_LOOK:
@@ -2653,9 +2652,9 @@ void Scene90::postInit(SceneObjectList *OwnerList) {
_globals->_sceneItems.push_back(&_object3);
_globals->_player.disableControl();
- _globals->_soundHandler.startSound(55);
- _soundHandler1.startSound(52);
- _soundHandler1.proc5(1);
+ _globals->_soundHandler.play(55);
+ _soundHandler1.play(52);
+ _soundHandler1.holdAt(true);
setAction(&_action1);
@@ -2670,7 +2669,7 @@ void Scene90::signal() {
switch (_sceneMode) {
case 91:
_sceneMode = 92;
- _globals->_soundHandler.startSound(77, this);
+ _globals->_soundHandler.play(77, this);
break;
case 92:
_globals->_scenePalette.clearListeners();
@@ -2713,7 +2712,7 @@ void Scene95::Action1::signal() {
setDelay(60);
break;
case 2: {
- scene->_soundHandler.startSound(66);
+ scene->_soundHandler.play(66);
scene->_object3._numFrames = 5;
scene->_object3.animate(ANIM_MODE_5, NULL);
SceneItem::display(0, 0);
@@ -2728,7 +2727,7 @@ void Scene95::Action1::signal() {
break;
}
case 3: {
- scene->_soundHandler.startSound(21);
+ scene->_soundHandler.play(21);
Common::Point pt1(235, 72);
PlayerMover *mover1 = new PlayerMover();
@@ -2768,7 +2767,7 @@ void Scene95::Action1::signal() {
scene->_object1.setVisage(91);
scene->_object1.setPosition(Common::Point(-22, 220));
- scene->_soundHandler.startSound(21);
+ scene->_soundHandler.play(21);
Common::Point pt1(5, 198);
NpcMover *mover1 = new NpcMover();
@@ -2826,7 +2825,7 @@ void Scene95::postInit(SceneObjectList *OwnerList) {
_object3.setVisage(96);
_object3.setPosition(Common::Point(29, 198));
- _soundHandler.startSound(67);
+ _soundHandler.play(67);
setAction(&_action1);
}
@@ -2890,7 +2889,7 @@ void Scene6100::Action3::signal() {
scene->_sunflower3.hide();
scene->_rocks.hide();
scene->_sceneText.hide();
-
+
_globals->_events.setCursor(CURSOR_WALK);
scene->_stripManager.start(8120, this);
break;
@@ -3000,21 +2999,21 @@ void Scene6100::Action5::dispatch() {
(tempSet.sqrt(zeroSet) < 150.0)) {
switch (scene->_hitCount++) {
case 0:
- scene->_soundHandler.startSound(233);
+ scene->_soundHandler.play(233);
scene->showMessage(NULL, 0, NULL);
if (!_globals->getFlag(76))
scene->_probe.setAction(&scene->_action1);
break;
case 1:
- scene->_soundHandler.startSound(233);
+ scene->_soundHandler.play(233);
scene->showMessage(NULL, 0, NULL);
if (!_globals->getFlag(76))
scene->_probe.setAction(&scene->_action2);
break;
case 2:
- scene->_soundHandler.startSound(234);
+ scene->_soundHandler.play(234);
scene->showMessage(NULL, 0, NULL);
if (!_globals->getFlag(76))
@@ -3243,7 +3242,7 @@ void Scene6100::postInit(SceneObjectList *OwnerList) {
if (!_globals->getFlag(76))
_probe.setAction(&_action4);
- _globals->_soundHandler.startSound(231);
+ _globals->_soundHandler.play(231);
}
void Scene6100::remove() {
diff --git a/engines/tsage/ringworld_scenes1.h b/engines/tsage/ringworld_scenes1.h
index abd765473c..283cf68e07 100644
--- a/engines/tsage/ringworld_scenes1.h
+++ b/engines/tsage/ringworld_scenes1.h
@@ -30,6 +30,7 @@
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
+#include "tsage/sound.h"
namespace tSage {
@@ -65,7 +66,7 @@ class Scene15 : public Scene {
public:
Action1 _action1;
SceneObject _object1;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
@@ -97,7 +98,7 @@ public:
Action3 _action3;
Action4 _action4;
SceneObject _sceneObject1, _SceneObjectExt, _sceneObject3, _sceneObject4, _sceneObject5;
- SoundHandler _sound;
+ ASound _sound;
public:
Scene20();
virtual ~Scene20() {}
@@ -143,7 +144,7 @@ class Scene30 : public Scene {
};
public:
- SoundHandler _sound;
+ ASound _sound;
DisplayHotspot _groundHotspot, _wallsHotspot, _courtyardHotspot, _treeHotspot;
BeamObject _beam;
DoorObject _door;
@@ -232,7 +233,7 @@ public:
SpeakerQText _speakerQText;
SpeakerSText _speakerSText;
SpeakerGameText _speakerGameText;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
Action1 _action1;
Action2 _action2;
Action3 _action3;
@@ -271,7 +272,7 @@ class Scene50 : public Scene {
public:
virtual void signal();
};
-
+
/* Objects */
class Object1 : public SceneObject {
public:
@@ -311,7 +312,7 @@ public:
virtual void dispatch();
};
-class Scene60 : public Scene {
+class Scene60 : public Scene {
class Action1 : public Action {
public:
virtual void signal();
@@ -387,9 +388,9 @@ public:
SceneObject _redLights;
Item1 _item1;
Item _item2, _item3, _item4, _item5, _item6;
- SoundHandler _soundHandler1;
- SoundHandler _soundHandler2;
- SoundHandler _soundHandler3;
+ ASound _soundHandler1;
+ ASound _soundHandler2;
+ ASound _soundHandler3;
Scene60();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -423,7 +424,7 @@ public:
DisplayObject _object3, _object4, _object5;
SceneObject _object6;
DisplayHotspot _item1, _item2, _item3;
- SoundHandler _soundHandler1, _soundHandler2;
+ ASound _soundHandler1, _soundHandler2;
Scene90();
@@ -441,7 +442,7 @@ class Scene95 : public Scene {
public:
Action1 _action1;
SceneObject _object1, _object2, _object3;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
Scene95();
virtual void postInit(SceneObjectList *OwnerList);
@@ -505,7 +506,7 @@ public:
Action5 _action5;
GetBoxAction _getBoxAction;
Action7 _action7;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
Speaker _speaker1;
SpeakerQR _speakerQR;
SpeakerSL _speakerSL;
diff --git a/engines/tsage/ringworld_scenes10.cpp b/engines/tsage/ringworld_scenes10.cpp
index 0b4186531d..ba4060548e 100644
--- a/engines/tsage/ringworld_scenes10.cpp
+++ b/engines/tsage/ringworld_scenes10.cpp
@@ -151,7 +151,7 @@ void Scene9100::postInit(SceneObjectList *OwnerList) {
_sceneHotspot5.setup(69, 36, 121, 272, 9100, 45, 46);
_sceneHotspot6.setup(127, 0, 200, 52, 9100, 47, 48);
- _globals->_soundHandler.startSound(251);
+ _globals->_soundHandler.play(251);
if (_globals->_sceneManager._previousScene == 9150) {
if (_globals->getFlag(20)) {
_globals->_player.disableControl();
@@ -236,7 +236,7 @@ void Scene9150::dispatch() {
} else {
_globals->_player.disableControl();
if (_globals->getFlag(11)) {
- _globals->_soundHandler.startSound(286);
+ _globals->_soundHandler.play(286);
_sceneMode = 9153;
} else {
_sceneMode = 9156;
@@ -270,7 +270,7 @@ void Scene9150::postInit(SceneObjectList *OwnerList) {
_sceneHotspot8.setup(133, 584, 142, 640, 9150, 57, -1);
_sceneHotspot10.setup(83, 304, 103, 323, 9150, 58, 59);
- _globals->_soundHandler.startSound(285);
+ _globals->_soundHandler.play(285);
_globals->_player.disableControl();
if (_globals->getFlag(20)) {
@@ -402,7 +402,8 @@ void Scene9200::postInit(SceneObjectList *OwnerList) {
_object1.animate(ANIM_MODE_2, NULL);
_object1.setPosition(Common::Point(132, 114));
_object1.fixPriority(140);
- _soundHandler.startSound(297);
+ _soundHandler.play(297);
+
_stripManager.addSpeaker(&_speakerQText);
_stripManager.addSpeaker(&_speakerGR);
_stripManager.addSpeaker(&_speakerGText);
@@ -479,7 +480,7 @@ void Scene9300::signal() {
_globals->setFlag(84);
// No break on purpose
case 9303:
- _globals->_soundHandler.startSound(295);
+ _globals->_soundHandler.play(295);
_globals->_sceneManager.changeScene(9350);
break;
case 9302:
@@ -509,7 +510,7 @@ void Scene9300::postInit(SceneObjectList *OwnerList) {
_globals->_player.changeZoom(-1);
_object1.postInit();
_object2.postInit();
- _globals->_soundHandler.startSound(289);
+ _globals->_soundHandler.play(289);
_hotspot1.setup(35, 142, 76, 212, 9300, 0, 1);
_hotspot2.setup(28, 90, 81, 143, 9300, 2, 3);
@@ -764,7 +765,7 @@ void Scene9400::signal() {
void Scene9400::dispatch() {
if ((_object1._animateMode == 2) && (_object1._strip == 1) && (_object1._frame == 4)){
if (_field1032 == 0) {
- _soundHandler.startSound(296);
+ _soundHandler.play(296);
_field1032 = 1;
}
} else {
@@ -1083,7 +1084,7 @@ void Scene9500::signal() {
switch (_sceneMode) {
case 9503:
_globals->_sceneManager.changeScene(9200);
- _globals->_soundHandler.startSound(295);
+ _globals->_soundHandler.play(295);
break;
case 9504:
_globals->_sceneManager.changeScene(9850);
@@ -1141,7 +1142,7 @@ void Scene9500::postInit(SceneObjectList *OwnerList) {
setZoomPercents(110, 75, 200, 150);
_globals->_player.postInit();
- _globals->_soundHandler.startSound(305);
+ _globals->_soundHandler.play(305);
_candle.postInit();
_candle.setVisage(9500);
@@ -1249,7 +1250,7 @@ void Scene9700::signal() {
_globals->_events.setCursor(CURSOR_USE);
break;
case 9704:
- _globals->_soundHandler.startSound(323);
+ _globals->_soundHandler.play(323);
_globals->_sceneManager.changeScene(9750);
break;
}
@@ -1308,7 +1309,7 @@ void Scene9700::postInit(SceneObjectList *OwnerList) {
void Scene9750::signal() {
switch (_sceneMode ++) {
case 9751:
- _globals->_soundHandler.proc1(this);
+ _globals->_soundHandler.fadeOut(this);
break;
case 9752:
_globals->_sceneManager.changeScene(2100);
@@ -1440,7 +1441,7 @@ void Scene9850::Hotspot17::doAction(int action) {
SceneItem::display(9850, 32, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
} else {
if (action == CURSOR_USE)
- scene->_soundHandler.startSound(306);
+ scene->_soundHandler.play(306);
NamedHotspot::doAction(action);
}
}
@@ -1452,7 +1453,7 @@ void Scene9850::Hotspot18::doAction(int action) {
SceneItem::display(9850, 32, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
} else {
if (action == CURSOR_USE)
- scene->_soundHandler.startSound(306);
+ scene->_soundHandler.play(306);
NamedHotspot::doAction(action);
}
}
@@ -1464,7 +1465,7 @@ void Scene9850::Hotspot19::doAction(int action) {
SceneItem::display(9850, 31, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
} else {
if (action == CURSOR_USE)
- scene->_soundHandler.startSound(313);
+ scene->_soundHandler.play(313);
NamedHotspot::doAction(action);
}
}
@@ -1653,7 +1654,7 @@ void Scene9900::strAction1::signal() {
switch (_actionIndex++) {
case 0:
- scene->_soundHandler.startSound(351);
+ scene->_soundHandler.play(351);
_object9.postInit();
_object9.setVisage(18);
_object9._frame = 1;
@@ -1673,7 +1674,7 @@ void Scene9900::strAction1::signal() {
_globals->_scenePalette.addFader(&mask2[0], 1, 5, this);
break;
case 3:
- _globals->_soundHandler.startSound(377);
+ _globals->_soundHandler.play(377);
setDelay(120);
break;
case 4:
@@ -1854,7 +1855,7 @@ void Scene9900::signal() {
switch (_sceneMode){
case 150:
- _globals->_soundHandler.startSound(380);
+ _globals->_soundHandler.play(380);
_object8.postInit();
_object8.setVisage(2002);
_object8.setStrip(1);
@@ -1887,7 +1888,7 @@ void Scene9900::signal() {
setAction(&_sequenceManager, this, 9902, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
break;
case 9904:
- _globals->_soundHandler.startSound(390);
+ _globals->_soundHandler.play(390);
_sceneMode = 9912;
setAction(&_strAction2, this);
break;
@@ -1918,7 +1919,7 @@ void Scene9900::signal() {
setAction(&_sequenceManager, this, 9904, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
break;
case 9909:
- _globals->_soundHandler.startSound(375);
+ _globals->_soundHandler.play(375);
_globals->_player.disableControl();
_sceneMode = 9907;
setAction(&_sequenceManager, this, 9907, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
@@ -1929,7 +1930,7 @@ void Scene9900::signal() {
setAction(&_sequenceManager, this, 9911, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
break;
case 9911:
- _globals->_soundHandler.startSound(367);
+ _globals->_soundHandler.play(367);
_globals->_player.disableControl();
_sceneMode = 9909;
setAction(&_sequenceManager, this, 9909, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
@@ -2080,7 +2081,7 @@ void Scene9999::postInit(SceneObjectList *OwnerList) {
else
_globals->_stripNum = 2121;
- _globals->_soundHandler.startSound(118);
+ _globals->_soundHandler.play(118);
}
diff --git a/engines/tsage/ringworld_scenes10.h b/engines/tsage/ringworld_scenes10.h
index aa41555718..33b16d0014 100644
--- a/engines/tsage/ringworld_scenes10.h
+++ b/engines/tsage/ringworld_scenes10.h
@@ -129,7 +129,7 @@ public:
SpeakerGText _speakerGText;
SpeakerGR _speakerGR;
SpeakerQText _speakerQText;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SceneHotspot1 _hotspot1;
NamedHotspot _hotspot2;
NamedHotspot _hotspot3;
@@ -230,7 +230,7 @@ public:
NamedHotspot _hotspot4;
NamedHotspot _hotspot5;
NamedHotspot _hotspot6;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
int _field1032;
SceneHotspot7 _hotspot7;
SceneHotspot8 _hotspot8;
@@ -424,7 +424,7 @@ public:
SceneObject _objLever;
Object6 _objScimitar;
Object7 _objSword;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
NamedHotspot _hotspot1;
NamedHotspot _hotspot2;
NamedHotspot _hotspot3;
@@ -482,7 +482,7 @@ class Scene9900 : public Scene {
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SequenceManager _sequenceManager;
SceneObject _object1;
SceneObject _object2;
diff --git a/engines/tsage/ringworld_scenes2.cpp b/engines/tsage/ringworld_scenes2.cpp
index 4378eac724..0154123c3d 100644
--- a/engines/tsage/ringworld_scenes2.cpp
+++ b/engines/tsage/ringworld_scenes2.cpp
@@ -117,6 +117,7 @@ void Scene1000::Action3::signal() {
// First time being played, so show the introduction
ConfMan.setBool(SEEN_INTRO, true);
ConfMan.flushToDisk();
+
setDelay(1);
} else {
// Prompt user for whether to start play or watch introduction
@@ -124,7 +125,7 @@ void Scene1000::Action3::signal() {
if (MessageDialog::show2(WATCH_INTRO_MSG, START_PLAY_BTN_STRING, INTRODUCTION_BTN_STRING) == 0) {
_actionIndex = 20;
- _globals->_soundHandler.proc1(this);
+ _globals->_soundHandler.fadeOut(this);
} else {
setDelay(1);
}
@@ -214,7 +215,7 @@ void Scene1000::Action3::signal() {
case 18:
zoom(false);
_globals->_scenePalette.clearListeners();
- _globals->_soundHandler.proc1(this);
+ _globals->_soundHandler.fadeOut(this);
break;
case 19:
_globals->_sceneManager.changeScene(10);
@@ -267,7 +268,7 @@ void Scene1000::postInit(SceneObjectList *OwnerList) {
_globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
_globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
- _globals->_soundHandler.startSound(114);
+ _globals->_soundHandler.play(114);
} else if (_globals->_sceneManager._previousScene == 2222) {
setZoomPercents(150, 10, 180, 100);
_object1.postInit();
@@ -283,7 +284,7 @@ void Scene1000::postInit(SceneObjectList *OwnerList) {
setAction(&_action1);
} else {
- _globals->_soundHandler.startSound(4);
+ _globals->_soundHandler.play(4);
setZoomPercents(0, 10, 30, 100);
_object3.postInit();
_object3.setVisage(1050);
@@ -429,7 +430,7 @@ void Scene1001::Action1::signal() {
setDelay(10);
break;
case 16: {
- scene->_soundHandler1.startSound(90);
+ scene->_soundHandler1.play(90);
scene->_object6.postInit();
scene->_object6.setVisage(16);
@@ -446,7 +447,7 @@ void Scene1001::Action1::signal() {
break;
}
case 17: {
- scene->_soundHandler1.startSound(90);
+ scene->_soundHandler1.play(90);
scene->_object6.remove();
scene->_object7.postInit();
@@ -475,7 +476,7 @@ void Scene1001::Action1::signal() {
setDelay(30);
break;
case 19: {
- _globals->_soundHandler.startSound(91);
+ _globals->_soundHandler.play(91);
byte adjustData[4] = {0xff, 0xff, 0xff, 0};
_globals->_scenePalette.fade(adjustData, false, 0);
@@ -496,7 +497,7 @@ void Scene1001::Action1::signal() {
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 22:
- _globals->_soundHandler.startSound(92);
+ _globals->_soundHandler.play(92);
scene->_stripManager.start(111, this);
break;
case 23:
@@ -526,7 +527,7 @@ void Scene1001::postInit(SceneObjectList *OwnerList) {
_object3.setStrip2(4);
_object3.setPosition(Common::Point(61, 177));
- _globals->_soundHandler.startSound(85);
+ _globals->_soundHandler.play(85);
setAction(&_action1);
}
@@ -647,7 +648,7 @@ void Scene1250::postInit(SceneObjectList *OwnerList) {
setAction(&_action4);
} else {
setAction(&_action3);
- _globals->_soundHandler.startSound(114);
+ _globals->_soundHandler.play(114);
}
}
@@ -734,7 +735,7 @@ void Scene1400::Action1::signal() {
_globals->_sceneManager._scrollerRect = Rect(40, 20, 280, 180);
_globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
_globals->_stripNum = 1500;
- _globals->_soundHandler.proc3();
+ _globals->_soundHandler.stop();
_globals->_sceneManager.changeScene(1500);
break;
@@ -779,7 +780,7 @@ void Scene1400::postInit(SceneObjectList *OwnerList) {
_globals->_sceneOffset.y = (_globals->_sceneManager._scene->_sceneBounds.top / 100) * 100;
setAction(&_action1);
- _globals->_soundHandler.startSound(118);
+ _globals->_soundHandler.play(118);
}
/*--------------------------------------------------------------------------
@@ -842,7 +843,7 @@ void Scene1500::Action1::signal() {
setDelay(30);
break;
case 6:
- scene->_soundHandler.startSound(123);
+ scene->_soundHandler.play(123);
scene->_object1.setStrip2(4);
scene->_object1.setFrame(1);
scene->_object1.animate(ANIM_MODE_5, this);
@@ -850,13 +851,13 @@ void Scene1500::Action1::signal() {
case 7:
scene->_object1.setStrip2(5);
scene->_object1.animate(ANIM_MODE_2, NULL);
- scene->_soundHandler.startSound(124, this);
+ scene->_soundHandler.play(124, this);
break;
case 8:
- _globals->_soundHandler.startSound(126, this);
+ _globals->_soundHandler.play(126, this);
break;
case 9:
- _globals->_soundHandler.startSound(127);
+ _globals->_soundHandler.play(127);
_globals->_sceneManager.changeScene(2000);
break;
}
@@ -893,7 +894,7 @@ void Scene1500::Action2::signal() {
break;
}
case 3:
- scene->_soundHandler.proc4();
+ scene->_soundHandler.release();
_globals->_stripNum = 1505;
_globals->_sceneManager.changeScene(2400);
break;
@@ -907,7 +908,7 @@ void Scene1500::postInit(SceneObjectList *OwnerList) {
Scene::postInit();
if ((_globals->_stripNum == 1500) || ((_globals->_stripNum != 1504) && (_globals->_stripNum != 2751))) {
- _globals->_soundHandler.startSound(120);
+ _globals->_soundHandler.play(120);
setZoomPercents(105, 20, 145, 100);
setAction(&_action1);
diff --git a/engines/tsage/ringworld_scenes2.h b/engines/tsage/ringworld_scenes2.h
index 7731b45ae8..93a8f04fd4 100644
--- a/engines/tsage/ringworld_scenes2.h
+++ b/engines/tsage/ringworld_scenes2.h
@@ -72,7 +72,7 @@ public:
Action1 _action1;
SceneObject _object1, _object2, _object3, _object4;
SceneObject _object5, _object6, _object7;
- SoundHandler _soundHandler1, _soundHandler2;
+ ASound _soundHandler1, _soundHandler2;
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
@@ -134,7 +134,7 @@ public:
virtual void signal();
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
Action1 _action1;
Action2 _action2;
SceneObject _object1, _object2, _object3;
diff --git a/engines/tsage/ringworld_scenes3.cpp b/engines/tsage/ringworld_scenes3.cpp
index a19f15eca6..824a96a18b 100644
--- a/engines/tsage/ringworld_scenes3.cpp
+++ b/engines/tsage/ringworld_scenes3.cpp
@@ -129,11 +129,11 @@ void Scene2000::Action6::signal() {
setDelay(130);
break;
case 1:
- scene->_soundHandler2.startSound(79);
+ scene->_soundHandler2.play(79);
scene->_stripManager.start(2000, this);
break;
case 2:
- _globals->_soundHandler.startSound(81);
+ _globals->_soundHandler.play(81);
scene->_object6.postInit();
scene->_object6.setVisage(2003);
scene->_object6.setAction(NULL);
@@ -148,7 +148,7 @@ void Scene2000::Action6::signal() {
scene->_object6.animate(ANIM_MODE_6, this);
break;
case 5:
- _globals->_soundHandler.startSound(80);
+ _globals->_soundHandler.play(80);
scene->_object6.remove();
_globals->_sceneManager.changeScene(1001);
break;
@@ -308,12 +308,12 @@ void Scene2000::Action14::signal() {
setDelay(60);
break;
case 3:
- _globals->_soundHandler.startSound(99);
+ _globals->_soundHandler.play(99);
scene->_object8.show();
scene->_object8.animate(ANIM_MODE_5, this);
break;
case 4:
- _globals->_soundHandler.startSound(12);
+ _globals->_soundHandler.play(12);
scene->_object8.setStrip(2);
scene->_object8.setFrame(1);
scene->_object9.show();
@@ -324,7 +324,7 @@ void Scene2000::Action14::signal() {
scene->_stripManager.start(2001, this, scene);
break;
case 6:
- _globals->_soundHandler.proc1(0/* was false */);
+ _globals->_soundHandler.fadeOut(0/* was false */);
scene->_object8.setStrip(1);
scene->_object8.setFrame(scene->_object8.getFrameCount());
scene->_object8.animate(ANIM_MODE_6, this);
@@ -333,7 +333,7 @@ void Scene2000::Action14::signal() {
scene->_object10.remove();
break;
case 7:
- _globals->_soundHandler.startSound(111);
+ _globals->_soundHandler.play(111);
scene->_object8.remove();
setDelay(5);
break;
@@ -425,11 +425,11 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
setAction(&_action13);
break;
case 2200:
- _globals->_soundHandler.startSound(111);
+ _globals->_soundHandler.play(111);
setAction(&_action14);
break;
case 2222:
- _globals->_soundHandler.startSound(115);
+ _globals->_soundHandler.play(115);
setAction(&_action8);
break;
case 3500:
@@ -437,12 +437,12 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
break;
default:
_object6.remove();
- _globals->_soundHandler.startSound(80);
+ _globals->_soundHandler.play(80);
setAction(&_action6);
break;
}
- _soundHandler1.startSound(78);
+ _soundHandler1.play(78);
_globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
_globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
}
@@ -502,7 +502,7 @@ void Scene2100::Action1::signal() {
break;
}
case 2:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 3: {
@@ -551,7 +551,7 @@ void Scene2100::Action1::signal() {
}
}
- scene->_soundHandler.startSound(161);
+ scene->_soundHandler.play(161);
scene->_area1.restore();
scene->_area2.restore();
scene->_area3.restore();
@@ -560,7 +560,7 @@ void Scene2100::Action1::signal() {
if (_state == 2100) {
setDelay(1);
} else {
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, this);
}
break;
@@ -576,7 +576,7 @@ void Scene2100::Action1::signal() {
break;
case 7:
_globals->_player.fixPriority(-1);
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, this);
break;
case 8:
@@ -776,17 +776,17 @@ void Scene2100::Action9::signal() {
scene->_stripManager.start(6050, this);
break;
case 2:
- scene->_soundHandler.startSound(99);
+ scene->_soundHandler.play(99);
scene->_object4.show();
scene->_object4.animate(ANIM_MODE_5, this);
break;
case 3:
- scene->_soundHandler.startSound(12);
+ scene->_soundHandler.play(12);
scene->_object4.setStrip(2);
scene->_stripManager.start(6051, this, scene);
break;
case 4:
- scene->_soundHandler.proc1(0/* was false */);
+ scene->_soundHandler.fadeOut(0/* was false */);
scene->_object4.setStrip(1);
scene->_object4.setFrame(scene->_object4.getFrameCount());
scene->_object4.animate(ANIM_MODE_6, this);
@@ -847,7 +847,7 @@ void Scene2100::Action10::signal() {
break;
}
case 5:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 6: {
@@ -880,7 +880,7 @@ void Scene2100::Action10::signal() {
setDelay(45);
break;
case 9:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, this);
break;
case 10:
@@ -924,7 +924,7 @@ void Scene2100::Action11::signal() {
break;
}
case 3:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 4: {
@@ -945,7 +945,7 @@ void Scene2100::Action11::signal() {
setDelay(45);
break;
case 6:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, this);
break;
case 7:
@@ -970,7 +970,7 @@ void Scene2100::Action12::signal() {
scene->_stripManager.start(6000, this);
break;
case 2:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 3: {
@@ -984,7 +984,7 @@ void Scene2100::Action12::signal() {
break;
}
case 4: {
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, NULL);
_globals->_player.fixPriority(-1);
@@ -1096,7 +1096,7 @@ void Scene2100::Action14::signal() {
scene->_stripManager.start(6008, this);
break;
case 4:
- scene->_soundHandler.startSound(99);
+ scene->_soundHandler.play(99);
scene->_object4.show();
scene->_object4.animate(ANIM_MODE_5, this);
break;
@@ -1105,7 +1105,7 @@ void Scene2100::Action14::signal() {
scene->_stripManager.start(6009, this, scene);
break;
case 6:
- scene->_soundHandler.proc1(0/* was false */);
+ scene->_soundHandler.fadeOut(0/* was false */);
scene->_object4.setStrip(1);
scene->_object4.setFrame(scene->_object4.getFrameCount());
scene->_object4.animate(ANIM_MODE_6, this);
@@ -1136,7 +1136,7 @@ void Scene2100::Action14::signal() {
break;
}
case 10:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 11: {
@@ -1151,7 +1151,7 @@ void Scene2100::Action14::signal() {
break;
case 13:
scene->_object3.fixPriority(1);
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, this);
break;
case 14:
@@ -1180,7 +1180,7 @@ void Scene2100::Action15::signal() {
scene->_object3.fixPriority(1);
scene->_object3.changeZoom(-1);
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 2: {
@@ -1191,7 +1191,7 @@ void Scene2100::Action15::signal() {
break;
}
case 3: {
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, this);
Common::Point pt(272, 140);
@@ -1251,7 +1251,7 @@ void Scene2100::Action16::signal() {
break;
}
case 5:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 6: {
@@ -1266,7 +1266,7 @@ void Scene2100::Action16::signal() {
setDelay(45);
break;
case 8:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_object1.animate(ANIM_MODE_6, this);
break;
case 9:
@@ -1295,17 +1295,17 @@ void Scene2100::Action17::signal() {
scene->_stripManager.start(7070, this);
break;
case 4:
- scene->_soundHandler.startSound(99);
+ scene->_soundHandler.play(99);
scene->_object4.show();
scene->_object4.animate(ANIM_MODE_5, this);
break;
case 5:
- scene->_soundHandler.startSound(12);
+ scene->_soundHandler.play(12);
scene->_object4.setStrip(2);
scene->_stripManager.start(7071, this, scene);
break;
case 6:
- scene->_soundHandler.proc1(NULL);
+ scene->_soundHandler.fadeOut(NULL);
scene->_object4.setStrip(1);
scene->_object4.setFrame(scene->_object4.getFrameCount());
scene->_object4.animate(ANIM_MODE_6, this);
@@ -1690,8 +1690,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
switch (_globals->_sceneManager._previousScene) {
case 2120:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_object1.fixPriority(-1);
_globals->_player.fixPriority(-1);
_globals->_player.setPosition(Common::Point(80, 66));
@@ -1759,8 +1759,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
}
break;
case 3700:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
Scene::setZoomPercents(80, 75, 100, 90);
if (_globals->_sceneObjects->contains(&_object2))
@@ -1778,8 +1778,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 2105, &_object3, NULL);
break;
case 4250:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_globals->clearFlag(43);
_globals->_player.setVisage(2104);
@@ -1797,8 +1797,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 2107, &_object4, NULL);
break;
case 5000:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
if (_globals->_sceneObjects->contains(&_object2))
_object2.remove();
@@ -1814,8 +1814,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
setAction(&_action5);
break;
case 5100:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_globals->_player.setVisage(2104);
_globals->_player.setFrame(1);
_globals->_player.setPosition(Common::Point(65, 149));
@@ -1833,8 +1833,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
setAction(&_action9);
break;
case 7000:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
if (RING_INVENTORY._stasisBox2._sceneNumber == 1) {
_globals->_player.fixPriority(1);
@@ -1861,8 +1861,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
}
break;
case 7600:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
if (_globals->_sceneObjects->contains(&_object2))
_object2.remove();
@@ -1873,8 +1873,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
setAction(&_action8);
break;
case 8100:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_globals->_player.setVisage(2104);
_globals->_player.setFrame(1);
@@ -1886,8 +1886,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 2106, NULL);
break;
case 9750:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_globals->_player.setVisage(2104);
_globals->_player.setFrame(1);
@@ -1904,8 +1904,8 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 2103, &_object4, NULL);
break;
default:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_globals->_player._uiEnabled = true;
break;
@@ -1962,7 +1962,7 @@ void Scene2100::signal() {
void Scene2100::synchronize(Serializer &s) {
Scene::synchronize(s);
if (s.getVersion() >= 3)
- s.syncAsSint16LE(_sitFl);
+ s.syncAsSint16LE(_sitFl);
}
/*--------------------------------------------------------------------------
@@ -2074,7 +2074,7 @@ void Scene2120::Action1::dispatch() {
_actionIndex = !_entries[scene->_subjectIndex]._visage ? 4 : 3;
setDelay(30);
- scene->_soundHandler.startSound(159);
+ scene->_soundHandler.play(159);
}
// Next Page button handling
@@ -2105,7 +2105,7 @@ void Scene2120::Action1::dispatch() {
setDelay(30);
}
- scene->_soundHandler.startSound(159);
+ scene->_soundHandler.play(159);
}
// Previous Page button handling
@@ -2132,7 +2132,7 @@ void Scene2120::Action1::dispatch() {
break;
}
- scene->_soundHandler.startSound(159);
+ scene->_soundHandler.play(159);
}
// Exit button handling
@@ -2162,7 +2162,7 @@ void Scene2120::Action1::dispatch() {
setDelay(1);
}
- scene->_soundHandler.startSound(159);
+ scene->_soundHandler.play(159);
}
}
@@ -2232,7 +2232,7 @@ void Scene2150::Action1::signal() {
break;
}
case 1:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot1.animate(ANIM_MODE_5, this);
break;
case 2: {
@@ -2282,7 +2282,7 @@ void Scene2150::Action1::signal() {
}
}
- scene->_soundHandler.startSound(161);
+ scene->_soundHandler.play(161);
scene->_area1.restore();
scene->_area2.restore();
scene->_area3.restore();
@@ -2291,7 +2291,7 @@ void Scene2150::Action1::signal() {
if (_state == 2150) {
setDelay(1);
} else {
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot1.animate(ANIM_MODE_6, this);
}
break;
@@ -2306,7 +2306,7 @@ void Scene2150::Action1::signal() {
}
break;
case 6:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot1.animate(ANIM_MODE_6, this);
break;
case 7:
@@ -2333,10 +2333,10 @@ void Scene2150::Action2::signal() {
_globals->_player.setStrip(8);
_globals->_player.animate(ANIM_MODE_8, 1, this);
- scene->_soundHandler.startSound(163);
+ scene->_soundHandler.play(163);
break;
case 2:
- scene->_soundHandler.startSound(164);
+ scene->_soundHandler.play(164);
scene->_hotspot10.animate(ANIM_MODE_5, this);
break;
case 3:
@@ -2361,7 +2361,7 @@ void Scene2150::Action2::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 5:
- scene->_soundHandler.startSound(164);
+ scene->_soundHandler.play(164);
scene->_hotspot10.animate(ANIM_MODE_6, NULL);
scene->_hotspot14.remove();
@@ -2559,8 +2559,8 @@ void Scene2150::postInit(SceneObjectList *OwnerList) {
switch (_globals->_sceneManager._previousScene) {
case 2120:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_globals->_player.setPosition(Common::Point(108, 99));
break;
case 2200:
@@ -2709,7 +2709,7 @@ void Scene2200::Action3::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_soundHandler2.startSound(103);
+ scene->_soundHandler2.play(103);
scene->_hotspot4.setStrip(4);
scene->_hotspot4.animate(ANIM_MODE_NONE, NULL);
@@ -2726,7 +2726,7 @@ void Scene2200::Action3::signal() {
break;
}
case 1:
- scene->_soundHandler2.startSound(104);
+ scene->_soundHandler2.play(104);
scene->_hotspot4.setStrip(2);
scene->_hotspot4.setFrame(2);
setDelay(120);
@@ -2882,7 +2882,7 @@ void Scene2200::Hotspot9::doAction(int action) {
break;
case OBJECT_INFODISK:
if (_globals->_sceneManager._previousScene == 2310) {
- scene->_soundHandler2.startSound(35);
+ scene->_soundHandler2.play(35);
_globals->_player.disableControl();
scene->setAction(&scene->_action3);
}
@@ -2943,8 +2943,8 @@ void Scene2200::postInit(SceneObjectList *OwnerList) {
_hotspot8.remove();
break;
case 4000:
- _globals->_soundHandler.startSound(100);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(100);
+ _globals->_soundHandler.holdAt(true);
_globals->_player.remove();
_hotspot5.remove();
_hotspot8.remove();
@@ -2984,9 +2984,9 @@ void Scene2200::postInit(SceneObjectList *OwnerList) {
_hotspot4.fixPriority(255);
_globals->_sceneItems.push_back(&_hotspot4);
- _soundHandler1.startSound(101);
- _soundHandler2.startSound(100);
- _globals->_soundHandler.proc5(true);
+ _soundHandler1.play(101);
+ _soundHandler2.play(100);
+ _globals->_soundHandler.holdAt(true);
_globals->_sceneItems.push_back(&_hotspot5);
setAction(&_action2);
@@ -3139,7 +3139,7 @@ void Scene2222::postInit(SceneObjectList *OwnerList) {
setAction(&_action1);
}
- _soundHandler.startSound(116);
+ _soundHandler.play(116);
_globals->_sceneManager._scene->_sceneBounds.center(_hotspot1._position);
_globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
@@ -3225,7 +3225,7 @@ void Scene2230::Action2::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 3:
- scene->_soundHandler.startSound(157);
+ scene->_soundHandler.play(157);
_globals->_player._moveDiff = Common::Point(1, 1);
_globals->_player.setAction(&scene->_action4);
_globals->_player._uiEnabled = true;
@@ -3249,7 +3249,7 @@ void Scene2230::Action3::signal() {
NpcMover *mover = new NpcMover();
_globals->_player.addMover(mover, &pt, this);
- scene->_soundHandler.proc3();
+ scene->_soundHandler.stop();
break;
}
case 1:
@@ -3368,7 +3368,7 @@ void Scene2230::Action7::signal() {
break;
}
case 2: {
- scene->_soundHandler.startSound(158);
+ scene->_soundHandler.play(158);
scene->_hotspot8.setStrip2(2);
Common::Point pt(scene->_hotspot8._position.x, 97);
@@ -3451,7 +3451,7 @@ void Scene2230::Action8::signal() {
scene->_hotspot2.animate(ANIM_MODE_6, this);
break;
case 4: {
- scene->_soundHandler.startSound(158);
+ scene->_soundHandler.play(158);
scene->_hotspot2.remove();
scene->_hotspot8._frame = 1;
@@ -3774,7 +3774,7 @@ void Scene2280::Action1::signal() {
break;
}
case 1:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot16.animate(ANIM_MODE_5, this);
break;
case 2: {
@@ -3789,7 +3789,7 @@ void Scene2280::Action1::signal() {
break;
case 4:
_globals->_player.fixPriority(1);
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot16.animate(ANIM_MODE_6, this);
break;
case 5:
@@ -3810,7 +3810,7 @@ void Scene2280::Action2::signal() {
break;
}
case 1:
- scene->_soundHandler.startSound(265);
+ scene->_soundHandler.play(265);
_globals->_player.setVisage(2162);
_globals->_player._frame = 1;
@@ -3830,7 +3830,7 @@ void Scene2280::Action2::signal() {
scene->_hotspot12.remove();
break;
case 4:
- scene->_soundHandler.startSound(266);
+ scene->_soundHandler.play(266);
_globals->_player.setVisage(2170);
_globals->_player._frame = 1;
_globals->_player._strip = 4;
@@ -3858,7 +3858,7 @@ void Scene2280::Action3::signal() {
break;
}
case 1:
- scene->_soundHandler.startSound(265);
+ scene->_soundHandler.play(265);
_globals->_player.setVisage(2162);
_globals->_player._frame = 6;
@@ -4338,8 +4338,8 @@ void Scene2280::postInit(SceneObjectList *OwnerList) {
_sceneMode = 2281;
setAction(&_sequenceManager, this, 2281, &_globals->_player, &_hotspot16, NULL);
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
}
_globals->_sceneItems.addItems(&_hotspot13, &_hotspot11, &_hotspot9, &_hotspot14, &_hotspot7,
@@ -4390,7 +4390,7 @@ void Scene2300::Action1::signal() {
}
case 2: {
scene->_hotspot8.setAction(&scene->_action4);
- scene->_soundHandler2.startSound(21);
+ scene->_soundHandler2.play(21);
Common::Point pt1(95, scene->_hotspot5._position.y);
NpcMover *mover1 = new NpcMover();
@@ -4428,7 +4428,7 @@ void Scene2300::Action1::signal() {
break;
}
case 6:
- scene->_soundHandler1.startSound(28);
+ scene->_soundHandler1.play(28);
_globals->_player.disableControl();
scene->_hotspot2.setVisage(40);
@@ -4442,7 +4442,7 @@ void Scene2300::Action1::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 7:
- _globals->_soundHandler.startSound(77, this);
+ _globals->_soundHandler.play(77, this);
break;
case 8:
_globals->_game->endGame(2300, 0);
@@ -4470,7 +4470,7 @@ void Scene2300::Action1::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 11:
- scene->_soundHandler1.startSound(28);
+ scene->_soundHandler1.play(28);
scene->_hotspot5._strip = 2;
scene->_hotspot6._strip = 2;
@@ -4487,7 +4487,7 @@ void Scene2300::Action1::signal() {
_globals->_player.animate(ANIM_MODE_6, this);
break;
case 12:
- scene->_soundHandler1.startSound(77);
+ scene->_soundHandler1.play(77);
_globals->_player.setVisage(0);
_globals->_player.animate(ANIM_MODE_1, NULL);
_globals->_player.setStrip(4);
@@ -4565,8 +4565,8 @@ void Scene2300::Action2::signal() {
scene->_hotspot2.setFrame(1);
scene->_hotspot2.animate(ANIM_MODE_5, this);
- scene->_soundHandler1.startSound(28);
- scene->_soundHandler2.startSound(97);
+ scene->_soundHandler1.play(28);
+ scene->_soundHandler2.play(97);
break;
case 7:
scene->_hotspot7._strip = 2;
@@ -4610,8 +4610,8 @@ void Scene2300::Action3::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 3:
- scene->_soundHandler1.startSound(97);
- scene->_soundHandler2.startSound(28);
+ scene->_soundHandler1.play(97);
+ scene->_soundHandler2.play(28);
scene->_hotspot7._strip = 2;
scene->_hotspot7._frame = 1;
@@ -4623,7 +4623,7 @@ void Scene2300::Action3::signal() {
_globals->_player.animate(ANIM_MODE_6, NULL);
break;
case 4:
- scene->_soundHandler2.startSound(97);
+ scene->_soundHandler2.play(97);
_globals->_player.setVisage(0);
_globals->_player.animate(ANIM_MODE_1, NULL);
_globals->_player.setStrip(1);
@@ -4645,7 +4645,7 @@ void Scene2300::Action4::signal() {
switch (_actionIndex++) {
case 0:
scene->_hotspot8.animate(ANIM_MODE_5, this);
- scene->_soundHandler1.startSound(11);
+ scene->_soundHandler1.play(11);
break;
case 1:
scene->_hotspot9.postInit();
@@ -4655,7 +4655,7 @@ void Scene2300::Action4::signal() {
scene->_hotspot9.setPosition(Common::Point(273, 199));
scene->_hotspot9.fixPriority(19);
scene->_hotspot9.animate(ANIM_MODE_5, this);
- scene->_soundHandler1.startSound(11);
+ scene->_soundHandler1.play(11);
break;
case 2:
scene->_hotspot8.remove();
@@ -4666,10 +4666,10 @@ void Scene2300::Action4::signal() {
scene->_hotspot10.setFrame(4);
scene->_hotspot10.setPosition(Common::Point(292, 113));
scene->_hotspot10.animate(ANIM_MODE_5, this);
- scene->_soundHandler1.startSound(11);
+ scene->_soundHandler1.play(11);
break;
case 3:
- scene->_soundHandler1.startSound(13);
+ scene->_soundHandler1.play(13);
remove();
break;
}
@@ -4747,7 +4747,7 @@ void Scene2300::postInit(SceneObjectList *OwnerList) {
_hotspot8.setVisage(2301);
_hotspot8.setPosition(Common::Point(288, 74));
- _globals->_soundHandler.startSound(96);
+ _globals->_soundHandler.play(96);
if (_globals->_sceneManager._previousScene == 2000) {
_hotspot8.remove();
@@ -4778,8 +4778,8 @@ void Scene2300::postInit(SceneObjectList *OwnerList) {
_hotspot7.setPosition(Common::Point(229, 125));
_hotspot7._numFrames = 5;
- _soundHandler1.startSound(95);
- _soundHandler2.startSound(96);
+ _soundHandler1.play(95);
+ _soundHandler2.play(96);
_globals->_sceneItems.push_back(&_hotspot7);
setAction(&_action2);
@@ -5062,7 +5062,7 @@ void Scene2320::Action2::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_soundHandler.startSound(253);
+ scene->_soundHandler.play(253);
scene->_hotspot13.fixPriority(99);
Common::Point pt(scene->_hotspot13._position.x, 200);
@@ -5088,7 +5088,7 @@ void Scene2320::Action3::signal() {
break;
}
case 1:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot6.animate(ANIM_MODE_5, this);
break;
case 2: {
@@ -5137,7 +5137,7 @@ void Scene2320::Action3::signal() {
}
}
- scene->_soundHandler.startSound(161);
+ scene->_soundHandler.play(161);
scene->_area1.restore();
scene->_area2.restore();
scene->_area3.restore();
@@ -5146,7 +5146,7 @@ void Scene2320::Action3::signal() {
if (_state == 2320) {
setDelay(10);
} else {
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot6.animate(ANIM_MODE_6, this);
}
break;
@@ -5162,7 +5162,7 @@ void Scene2320::Action3::signal() {
break;
}
case 6:
- scene->_soundHandler.startSound(162);
+ scene->_soundHandler.play(162);
scene->_hotspot6.animate(ANIM_MODE_6, this);
break;
case 7:
@@ -5250,8 +5250,8 @@ void Scene2320::Action4::signal() {
break;
case 10:
if (_globals->getFlag(109)) {
- _globals->_soundHandler.startSound(40);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(40);
+ _globals->_soundHandler.holdAt(true);
Common::Point pt(303, 240);
NpcMover *mover = new NpcMover();
@@ -5311,7 +5311,7 @@ void Scene2320::Action4::signal() {
}
case 19: {
scene->_hotspot16.remove();
- scene->_soundHandler.startSound(253);
+ scene->_soundHandler.play(253);
scene->_hotspot13.show();
Common::Point pt(319, 157);
@@ -5462,7 +5462,7 @@ void Scene2320::Action7::signal() {
setDelay(30);
break;
case 1:
- _globals->_soundHandler.startSound(162);
+ _globals->_soundHandler.play(162);
scene->_hotspot6.animate(ANIM_MODE_5, this);
break;
case 2:
@@ -5889,8 +5889,8 @@ void Scene2320::postInit(SceneObjectList *OwnerList) {
switch (_globals->_sceneManager._previousScene) {
case 2120:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_globals->_player.fixPriority(-1);
_globals->_player.setPosition(Common::Point(389, 72));
@@ -5907,8 +5907,8 @@ void Scene2320::postInit(SceneObjectList *OwnerList) {
case 4250:
case 5000:
case 7000:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
if ((_globals->_sceneManager._previousScene == 7000) && !_globals->getFlag(80))
_globals->setFlag(36);
@@ -5924,8 +5924,8 @@ void Scene2320::postInit(SceneObjectList *OwnerList) {
setAction(&_action6);
break;
case 6100:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_hotspot8.postInit();
_hotspot8.setVisage(2345);
@@ -5936,9 +5936,9 @@ void Scene2320::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 2325, &_globals->_player, &_hotspot6, &_hotspot8, &_hotspot7, NULL);
break;
case 7600:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
- _soundHandler.startSound(21);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
+ _soundHandler.play(21);
_globals->_player.setVisage(2323);
_globals->_player.setStrip(2);
@@ -5995,8 +5995,8 @@ void Scene2320::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 2325, &_globals->_player, &_hotspot6, &_hotspot8, &_hotspot7, NULL);
break;
default:
- _globals->_soundHandler.startSound(160);
- _globals->_soundHandler.proc5(true);
+ _globals->_soundHandler.play(160);
+ _globals->_soundHandler.holdAt(true);
_sceneMode = 2321;
_globals->_player.setStrip(3);
@@ -6127,7 +6127,7 @@ void Scene2400::postInit(SceneObjectList *OwnerList) {
_globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
_globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
- _globals->_soundHandler.startSound(153);
+ _globals->_soundHandler.play(153);
}
} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes3.h b/engines/tsage/ringworld_scenes3.h
index cc237a1f91..711360c190 100644
--- a/engines/tsage/ringworld_scenes3.h
+++ b/engines/tsage/ringworld_scenes3.h
@@ -114,7 +114,7 @@ public:
Action14 _action14;
SceneObject _object1, _object2, _object3, _object4, _object5;
SceneObject _object6, _object7, _object8, _object9, _object10;
- SoundHandler _soundHandler1, _soundHandler2;
+ ASound _soundHandler1, _soundHandler2;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void stripCallback(int v);
@@ -232,7 +232,7 @@ class Scene2100 : public Scene {
};
public:
SequenceManager _sequenceManager;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SpeakerMText _speakerMText;
SpeakerMR _speakerMR;
SpeakerQL _speakerQL;
@@ -311,7 +311,7 @@ class Scene2120 : public Scene {
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SceneObject _topicArrowHotspot, _arrowHotspot, _visageHotspot;
SceneObject _subjectButton, _nextPageButton, _previousPageButton, _exitButton;
Action1 _action1;
@@ -359,7 +359,7 @@ class Scene2150 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SequenceManager _sequenceManager;
SpeakerGameText _speakerGameText;
@@ -440,7 +440,7 @@ public:
DisplayHotspot _hotspot10;
SceneObject _hotspot2, _hotspot4;
SceneObject _hotspot6, _hotspot7, _hotspot8;
- SoundHandler _soundHandler1, _soundHandler2;
+ ASound _soundHandler1, _soundHandler2;
Scene2200();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -462,7 +462,7 @@ class Scene2222 : public Scene {
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SpeakerSText _speakerSText;
SpeakerMText _speakerMText;
SpeakerQText _speakerQText;
@@ -552,7 +552,7 @@ class Scene2230 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
Action1 _action1;
Action2 _action2;
Action3 _action3;
@@ -652,7 +652,7 @@ class Scene2280 : public Scene {
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SequenceManager _sequenceManager;
Rect _exitRect;
Action1 _action1;
@@ -712,7 +712,7 @@ class Scene2300 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler1, _soundHandler2;
+ ASound _soundHandler1, _soundHandler2;
SpeakerSL _speakerSL;
SpeakerMText _speakerMText;
SpeakerQText _speakerQText;
@@ -834,7 +834,7 @@ class Scene2320 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SequenceManager _sequenceManager1, _sequenceManager2;
SpeakerMText _speakerMText;
SpeakerMR _speakerMR;
diff --git a/engines/tsage/ringworld_scenes4.cpp b/engines/tsage/ringworld_scenes4.cpp
index 883da9b5b1..838769e4af 100644
--- a/engines/tsage/ringworld_scenes4.cpp
+++ b/engines/tsage/ringworld_scenes4.cpp
@@ -178,7 +178,7 @@ void Scene3700::Action1::signal() {
setDelay(90);
break;
case 3:
- scene->_soundHandler.startSound(196);
+ scene->_soundHandler.play(196);
scene->_viewer.hide();
scene->_hotspot1.postInit();
@@ -190,7 +190,7 @@ void Scene3700::Action1::signal() {
setDelay(90);
break;
case 4:
- scene->_soundHandler.startSound(197);
+ scene->_soundHandler.play(197);
scene->_hotspot1.hide();
scene->_hotspot2.postInit();
@@ -202,7 +202,7 @@ void Scene3700::Action1::signal() {
setDelay(30);
break;
case 5:
- scene->_soundHandler.startSound(198);
+ scene->_soundHandler.play(198);
scene->_hotspot2.hide();
scene->_hotspot1.show();
setDelay(90);
@@ -244,7 +244,7 @@ void Scene3700::postInit(tSage::SceneObjectList *OwnerList) {
_viewer.setPosition(Common::Point(195, 83));
setAction(&_action1);
- _globals->_soundHandler.startSound(195);
+ _globals->_soundHandler.play(195);
}
} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes4.h b/engines/tsage/ringworld_scenes4.h
index 389c67b83a..0b575d02d3 100644
--- a/engines/tsage/ringworld_scenes4.h
+++ b/engines/tsage/ringworld_scenes4.h
@@ -82,7 +82,7 @@ public:
SpeakerSText _speakerSText;
SpeakerMText _speakerMText;
SpeakerMR _speakerMR;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
diff --git a/engines/tsage/ringworld_scenes5.cpp b/engines/tsage/ringworld_scenes5.cpp
index 8b95e40abe..fccc7e1b50 100644
--- a/engines/tsage/ringworld_scenes5.cpp
+++ b/engines/tsage/ringworld_scenes5.cpp
@@ -102,7 +102,7 @@ void Scene4000::Action1::signal() {
ADD_MOVER_NULL(scene->_hotspot5, -40, 86);
break;
case 5:
- _globals->_soundHandler.startSound(155);
+ _globals->_soundHandler.play(155);
_globals->setFlag(43);
_globals->setFlag(114);
scene->_stripManager.start(4430, this);
@@ -354,14 +354,14 @@ void Scene4000::Action8::signal() {
setDelay(60);
break;
case 3:
- _globals->_soundHandler.startSound(170);
+ _globals->_soundHandler.play(170);
scene->_smoke2.setVisage(4000);
scene->_smoke2.setStrip(6);
scene->_smoke2.animate(ANIM_MODE_2, NULL);
setDelay(60);
break;
case 4:
- _globals->_soundHandler.startSound(77, this);
+ _globals->_soundHandler.play(77, this);
break;
case 5:
_globals->_game->endGame(4000, 15);
@@ -429,7 +429,7 @@ void Scene4000::Action11::signal() {
scene->_olo.animate(ANIM_MODE_1, NULL);
break;
case 5:
- scene->_soundHandler1.proc3();
+ scene->_soundHandler1.stop();
scene->_forceField.remove();
ADD_MOVER(_globals->_player, 340, 163);
@@ -494,12 +494,12 @@ void Scene4000::Action13::signal() {
setDelay(3);
break;
case 1:
- scene->_soundHandler2.startSound(151);
- scene->_soundHandler2.proc5(true);
+ scene->_soundHandler2.play(151);
+ scene->_soundHandler2.holdAt(true);
ADD_MOVER(scene->_lander, -30, 70);
break;
case 2:
- scene->_soundHandler2.proc4();
+ scene->_soundHandler2.release();
_globals->_sceneManager.changeScene(4010);
break;
}
@@ -867,7 +867,7 @@ void Scene4000::postInit(SceneObjectList *OwnerList) {
_theTech.setPosition(Common::Point(281, 176));
if (_globals->getFlag(34)) {
- _soundHandler1.startSound(156);
+ _soundHandler1.play(156);
_forceField.postInit();
_forceField.setVisage(4000);
@@ -900,7 +900,7 @@ void Scene4000::postInit(SceneObjectList *OwnerList) {
switch (_globals->_sceneManager._previousScene) {
case 2320:
- _globals->_soundHandler.startSound(155);
+ _globals->_soundHandler.play(155);
if (RING_INVENTORY._ale._sceneNumber == 1) {
_guardRock.postInit();
@@ -962,7 +962,7 @@ void Scene4000::postInit(SceneObjectList *OwnerList) {
}
if (_globals->_stripNum == 4025) {
- _soundHandler1.startSound(182);
+ _soundHandler1.play(182);
_forceField.remove();
_hotspot5.postInit();
@@ -1043,7 +1043,7 @@ void Scene4000::postInit(SceneObjectList *OwnerList) {
break;
case 4050:
- _globals->_soundHandler.startSound(155);
+ _globals->_soundHandler.play(155);
_globals->_player.disableControl();
if (_globals->_stripNum == 4050) {
@@ -1080,7 +1080,7 @@ void Scene4000::postInit(SceneObjectList *OwnerList) {
break;
default:
- _globals->_soundHandler.startSound(155);
+ _globals->_soundHandler.play(155);
_lander.postInit();
_lander.setVisage(4002);
@@ -1104,7 +1104,7 @@ void Scene4000::postInit(SceneObjectList *OwnerList) {
RING_INVENTORY._ladder._sceneNumber = 4100;
RING_INVENTORY._rope._sceneNumber = 4150;
- _soundHandler1.startSound(156);
+ _soundHandler1.play(156);
_forceField.postInit();
_forceField.setVisage(4000);
@@ -1243,8 +1243,8 @@ void Scene4000::dispatch() {
if ((RING_INVENTORY._peg._sceneNumber == 1) && _globals->getFlag(34) &&
_globals->getFlag(37) && !_globals->getFlag(40)) {
_globals->_player.disableControl();
- _soundHandler1.startSound(177);
- _globals->_soundHandler.startSound(178);
+ _soundHandler1.play(177);
+ _globals->_soundHandler.play(178);
setAction(&_action1);
}
@@ -1892,7 +1892,7 @@ void Scene4045::postInit(SceneObjectList *OwnerList) {
_olloFace.fixPriority(152);
if(_globals->_sceneManager._previousScene == 4050) {
- _globals->_soundHandler.startSound(155);
+ _globals->_soundHandler.play(155);
_globals->_player.setPosition(Common::Point(72, 128));
_globals->_player.enableControl();
@@ -1921,7 +1921,7 @@ void Scene4045::postInit(SceneObjectList *OwnerList) {
_miranda.setStrip(3);
_miranda.setFrame(2);
_miranda.changeZoom(-1);
-
+
_miranda.setPosition(Common::Point(66, 209));
_globals->_sceneItems.push_back(&_miranda);
}
@@ -2273,7 +2273,7 @@ void Scene4050::postInit(SceneObjectList *OwnerList) {
_globals->_player.setStrip(2);
setAction(&_action2);
- _globals->_soundHandler.startSound(175);
+ _globals->_soundHandler.play(175);
} else {
// Without the rope
_globals->_player.setVisage(5315);
@@ -2284,7 +2284,7 @@ void Scene4050::postInit(SceneObjectList *OwnerList) {
_globals->_player.animate(ANIM_MODE_2, NULL);
setAction(&_action4);
- _globals->_soundHandler.startSound(176);
+ _globals->_soundHandler.play(176);
}
break;
case 4045:
@@ -2298,7 +2298,7 @@ void Scene4050::postInit(SceneObjectList *OwnerList) {
_globals->_player.setObjectWrapper(new SceneObjectWrapper());
_globals->_player.setPosition(Common::Point(193, 193));
- _globals->_soundHandler.startSound(175);
+ _globals->_soundHandler.play(175);
break;
default:
break;
@@ -2717,7 +2717,7 @@ void Scene4100::postInit(SceneObjectList *OwnerList) {
&_hotspot11, &_hotspot9, &_hotspot7, &_hotspot10, &_hotspot8, &_hotspot14, NULL);
if (_globals->_sceneManager._previousScene == 4150) {
- _globals->_soundHandler.startSound(155);
+ _globals->_soundHandler.play(155);
if (!_globals->getFlag(42)) {
_hotspot1.setVisage(4104);
@@ -3095,8 +3095,8 @@ void Scene4150::postInit(SceneObjectList *OwnerList) {
&_hotspot10, &_hotspot9, &_hotspot8, &_hotspot7, &_hotspot6, &_hotspot2,
&_hotspot5, NULL);
- _globals->_soundHandler.startSound(165);
- _soundHandler.startSound(311);
+ _globals->_soundHandler.play(165);
+ _soundHandler.play(311);
}
void Scene4150::signal() {
@@ -3110,8 +3110,8 @@ void Scene4150::dispatch() {
Scene::dispatch();
if (!_action && (_globals->_player._position.x >= 316)) {
- _globals->_soundHandler.proc1(NULL);
- _soundHandler.proc1(NULL);
+ _globals->_soundHandler.fadeOut(NULL);
+ _soundHandler.fadeOut(NULL);
_globals->_player.disableControl();
_sceneMode = 4152;
setAction(&_sequenceManager, this, 4152, &_globals->_player, NULL);
@@ -3414,7 +3414,7 @@ void Scene4250::Hotspot6::doAction(int action) {
SceneItem::display2(4250, (RING_INVENTORY._helmet._sceneNumber == 4250) ? 20 : 3);
break;
case OBJECT_HELMET:
- _globals->_soundHandler.startSound(354);
+ _globals->_soundHandler.play(354);
_globals->_player.disableControl();
RING_INVENTORY._helmet._sceneNumber = 4250;
@@ -3443,7 +3443,7 @@ void Scene4250::Hotspot6::doAction(int action) {
break;
case OBJECT_NULLIFIER:
if (RING_INVENTORY._helmet._sceneNumber == 4250) {
- _globals->_soundHandler.startSound(353);
+ _globals->_soundHandler.play(353);
_globals->_player.disableControl();
RING_INVENTORY._helmet._sceneNumber = 1;
@@ -3650,7 +3650,7 @@ void Scene4250::postInit(tSage::SceneObjectList *OwnerList) {
_hotspot7.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
_globals->_sceneItems.push_back(&_hotspot7);
- _globals->_soundHandler.startSound(185);
+ _globals->_soundHandler.play(185);
}
void Scene4250::signal() {
@@ -3683,7 +3683,7 @@ void Scene4250::signal() {
_globals->_player.enableControl();
break;
case 4259:
- _globals->_soundHandler.startSound(360);
+ _globals->_soundHandler.play(360);
_globals->_sceneManager.changeScene(9900);
break;
case 4261:
@@ -3751,36 +3751,36 @@ void Scene4300::Action1::signal() {
_globals->setFlag(56);
_globals->_scenePalette.addRotation(240, 254, -1);
scene->_hotspot7.animate(ANIM_MODE_6, this);
- _globals->_soundHandler.startSound(164);
+ _globals->_soundHandler.play(164);
break;
case 1:
- _globals->_soundHandler.startSound(340);
- scene->_soundHandler1.startSound(341);
+ _globals->_soundHandler.play(340);
+ scene->_soundHandler1.play(341);
scene->_hotspot1.remove();
setDelay(3);
break;
case 2:
- scene->_soundHandler1.startSound(341);
+ scene->_soundHandler1.play(341);
scene->_hotspot2.remove();
setDelay(6);
break;
case 3:
- scene->_soundHandler1.startSound(341);
+ scene->_soundHandler1.play(341);
scene->_hotspot3.remove();
setDelay(6);
break;
case 4:
- scene->_soundHandler1.startSound(341);
+ scene->_soundHandler1.play(341);
scene->_hotspot4.remove();
setDelay(12);
break;
case 5:
- scene->_soundHandler1.startSound(341);
+ scene->_soundHandler1.play(341);
scene->_hotspot5.remove();
setDelay(12);
break;
case 6:
- scene->_soundHandler1.startSound(341);
+ scene->_soundHandler1.play(341);
scene->_hotspot6.remove();
setDelay(60);
break;
@@ -3793,7 +3793,7 @@ void Scene4300::Action1::signal() {
scene->_stripManager.start(8015, this, scene);
break;
case 9:
- _globals->_soundHandler.startSound(350);
+ _globals->_soundHandler.play(350);
_globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
_globals->_events.setCursor(CURSOR_USE);
_globals->_player.enableControl();
@@ -3916,7 +3916,7 @@ void Scene4300::Hotspot10::doAction(int action) {
void Scene4300::Hotspot15::signal() {
Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene;
- scene->_soundHandler2.startSound(345);
+ scene->_soundHandler2.play(345);
_strip = (_globals->_randomSource.getRandomNumber(6) < 2) ? 2 : 1;
if ((RING_INVENTORY._stasisBox2._sceneNumber == 4300) ||
@@ -3982,7 +3982,7 @@ void Scene4300::Hotspot17::doAction(int action) {
SceneItem::display2(4300, 26);
break;
case OBJECT_STASIS_BOX2:
- scene->_soundHandler1.startSound(352);
+ scene->_soundHandler1.play(352);
_globals->_events.setCursor(CURSOR_USE);
scene->_sceneMode = 4303;
@@ -4241,11 +4241,11 @@ void Scene4301::Action1::signal() {
switch (_actionIndex++) {
case 0:
- scene->_soundHandler.startSound(164);
+ scene->_soundHandler.play(164);
scene->_hotspot1.animate(ANIM_MODE_5, this);
break;
case 1:
- _globals->_soundHandler.startSound(335);
+ _globals->_soundHandler.play(335);
_globals->_events.setCursor(CURSOR_USE);
scene->_hotspot2.postInit();
@@ -4268,9 +4268,9 @@ void Scene4301::Action1::signal() {
_actionIndex = 2;
break;
case 10:
- // Puzzle: Wrong code
+ // Puzzle: Wrong code
_globals->_events.setCursor(CURSOR_NONE);
- scene->_soundHandler.startSound(337);
+ scene->_soundHandler.play(337);
if (scene->_hotspot3._flags & OBJFLAG_HIDE)
scene->_hotspot3.show();
else
@@ -4285,7 +4285,7 @@ void Scene4301::Action1::signal() {
for (_state = 0; _state < 6; ++_state)
_buttonList[_state].remove();
- scene->_soundHandler.startSound(338);
+ scene->_soundHandler.play(338);
scene->_hotspot3.hide();
_actionIndex = 2;
@@ -4295,7 +4295,7 @@ void Scene4301::Action1::signal() {
case 20:
// Puzzle: Correct code
_globals->_player.disableControl();
- scene->_soundHandler.startSound(339);
+ scene->_soundHandler.play(339);
scene->_hotspot3._frame = 3;
if (scene->_hotspot3._flags & OBJFLAG_HIDE)
scene->_hotspot3.show();
@@ -4329,7 +4329,7 @@ void Scene4301::Action1::process(Event &event) {
if ((event.eventType == EVENT_BUTTON_DOWN) && buttonsRect.contains(event.mousePos)) {
event.handled = true;
- scene->_soundHandler.startSound(336);
+ scene->_soundHandler.play(336);
int buttonIndex = ((event.mousePos.y - buttonsRect.top) / 33) * 3 +
((event.mousePos.x - buttonsRect.left) / 33);
diff --git a/engines/tsage/ringworld_scenes5.h b/engines/tsage/ringworld_scenes5.h
index a2991c7283..c3ae9f4aa9 100644
--- a/engines/tsage/ringworld_scenes5.h
+++ b/engines/tsage/ringworld_scenes5.h
@@ -134,7 +134,7 @@ class Scene4000 : public Scene {
};
public:
SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3;
- SoundHandler _soundHandler1, _soundHandler2;
+ ASound _soundHandler1, _soundHandler2;
SpeakerQR _speakerQR;
SpeakerML _speakerML;
SpeakerMR _speakerMR;
@@ -471,7 +471,7 @@ class Scene4150 : public Scene {
public:
SequenceManager _sequenceManager;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SpeakerQText _speakerQText;
SpeakerQR _speakerQR;
SpeakerCDL _speakerCDL;
@@ -541,7 +541,7 @@ class Scene4250 : public Scene {
public:
SequenceManager _sequenceManager;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SpeakerSR _speakerSR;
SpeakerSL _speakerSL;
SpeakerSText _speakerSText;
@@ -613,7 +613,7 @@ class Scene4300 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler1, _soundHandler2;
+ ASound _soundHandler1, _soundHandler2;
SequenceManager _sequenceManager;
GfxButton _gfxButton;
SpeakerQText _speakerQText;
@@ -672,7 +672,7 @@ class Scene4301 : public Scene {
public:
Common::List<int> _list1;
SequenceManager _sequenceManager;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
Action1 _action1;
SceneObject _hotspot1, _hotspot2, _hotspot3;
Hotspot4 _hotspot4;
diff --git a/engines/tsage/ringworld_scenes6.cpp b/engines/tsage/ringworld_scenes6.cpp
index 9e5766d656..68c184196c 100644
--- a/engines/tsage/ringworld_scenes6.cpp
+++ b/engines/tsage/ringworld_scenes6.cpp
@@ -41,8 +41,8 @@ void Scene5000::Action1::signal() {
setDelay(10);
break;
case 1:
- scene->_soundHandler.startSound(190);
- scene->_soundHandler.proc5(true);
+ scene->_soundHandler.play(190);
+ scene->_soundHandler.holdAt(true);
ADD_MOVER(scene->_hotspot1, 283, 12);
break;
case 2:
@@ -55,7 +55,7 @@ void Scene5000::Action1::signal() {
setDelay(15);
break;
case 4:
- scene->_soundHandler.proc4();
+ scene->_soundHandler.release();
ADD_MOVER(scene->_hotspot1, 233, 80);
break;
case 5:
@@ -561,7 +561,7 @@ void Scene5000::postInit(SceneObjectList *OwnerList) {
break;
}
- _globals->_soundHandler.startSound(190);
+ _globals->_soundHandler.play(190);
}
void Scene5000::signal() {
@@ -639,7 +639,7 @@ void Scene5100::Action1::signal() {
}
break;
case 4:
- scene->_soundHandler.startSound(206);
+ scene->_soundHandler.play(206);
scene->_hotspot5.postInit();
scene->_hotspot5.setVisage(5362);
@@ -740,7 +740,7 @@ void Scene5100::Action3::signal() {
_globals->_player.animate(ANIM_MODE_5, this);
break;
case 2:
- scene->_soundHandler.startSound(28);
+ scene->_soundHandler.play(28);
if (static_cast<SceneObject *>(_owner)->_position.x < _globals->_player._position.x) {
scene->_hotspot2.setVisage(5130);
scene->_hotspot2._strip = 1;
@@ -786,7 +786,7 @@ void Scene5100::Action4::signal() {
switch (_actionIndex++) {
case 0: {
_globals->_player.disableControl();
- scene->_soundHandler.startSound(208);
+ scene->_soundHandler.play(208);
SceneItem::display2(5100, 15);
ObjectMover3 *mover = new ObjectMover3();
@@ -1289,7 +1289,7 @@ void Scene5100::postInit(SceneObjectList *OwnerList) {
_globals->_sceneManager._scene->_sceneBounds.center(_globals->_player._position);
loadScene(5100);
- _globals->_soundHandler.startSound(205);
+ _globals->_soundHandler.play(205);
}
void Scene5100::signal() {
@@ -1385,7 +1385,7 @@ void Scene5100::dispatch() {
_globals->_player.disableControl();
_globals->_player.addMover(NULL);
- _soundHandler.startSound(207);
+ _soundHandler.play(207);
_sceneMode = 5103;
setAction(&_sequenceManager, this, (_globals->_player._position.x >= 966) ? 5104 : 5103,
&_globals->_player, &_hotspot15, NULL);
@@ -1396,7 +1396,7 @@ void Scene5100::dispatch() {
(_globals->_sceneManager._previousScene != 5200) && (_sceneMode != 5150)) {
setAction(NULL);
_sceneMode = 5150;
- _soundHandler.startSound(208);
+ _soundHandler.play(208);
if (RING_INVENTORY._vial._sceneNumber == 5100) {
_globals->_player.addMover(NULL);
@@ -1471,7 +1471,7 @@ void Scene5200::Action2::signal() {
_globals->_player.animate(ANIM_MODE_4, 3, 1, this);
break;
case 2:
- scene->_soundHandler.proc3();
+ scene->_soundHandler.stop();
scene->_hotspot14.remove();
RING_INVENTORY._stasisBox._sceneNumber = 1;
@@ -1486,7 +1486,7 @@ void Scene5200::Action2::signal() {
ADD_MOVER(scene->_hotspot8, 141, 77);
break;
case 4:
- scene->_soundHandler.startSound(303);
+ scene->_soundHandler.play(303);
scene->_hotspot8._strip = 2;
scene->_hotspot8._frame = 1;
@@ -1523,7 +1523,7 @@ void Scene5200::Action4::signal() {
setDelay(120);
break;
case 1:
- _globals->_soundHandler.startSound(209);
+ _globals->_soundHandler.play(209);
scene->_stripManager.start(5202, this, scene);
break;
case 2:
@@ -1622,8 +1622,8 @@ void Scene5200::postInit(SceneObjectList *OwnerList) {
_speakerQText._textPos.x = 20;
if (RING_INVENTORY._stasisBox._sceneNumber == 5200) {
- _soundHandler.startSound(216);
- _soundHandler.proc5(true);
+ _soundHandler.play(216);
+ _soundHandler.holdAt(true);
_hotspot14.postInit();
_hotspot14.setVisage(5202);
@@ -1643,7 +1643,7 @@ void Scene5200::postInit(SceneObjectList *OwnerList) {
// Happens when the player enters the throne room via the secret passage,
// after talking with the bat. No NPCs are around and the player can
// obtain the stasis box.
- _globals->_soundHandler.startSound(205);
+ _globals->_soundHandler.play(205);
_globals->_player.disableControl();
_globals->_player.postInit();
@@ -2131,7 +2131,7 @@ void Scene5300::postInit(SceneObjectList *OwnerList) {
_hotspot8._sceneRegionId = 8;
_globals->_sceneItems.addItems(&_hotspot8, &_hotspot2, &_hotspot6, &_hotspot3, &_hotspot7, NULL);
- _globals->_soundHandler.startSound(212);
+ _globals->_soundHandler.play(212);
}
void Scene5300::signal() {
@@ -2141,7 +2141,7 @@ void Scene5300::signal() {
_globals->_sceneManager.changeScene(5100);
break;
case 5307:
- _soundHandler.proc1(NULL);
+ _soundHandler.fadeOut(NULL);
// No break on purpose
case 5302:
case 5308:
diff --git a/engines/tsage/ringworld_scenes6.h b/engines/tsage/ringworld_scenes6.h
index 6ac73d4bff..2e99f5ab87 100644
--- a/engines/tsage/ringworld_scenes6.h
+++ b/engines/tsage/ringworld_scenes6.h
@@ -75,7 +75,7 @@ class Scene5000 : public Scene {
};
public:
SequenceManager _sequenceManager;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SpeakerSText _speakerSText;
SpeakerQText _speakerQText;
Action1 _action1;
@@ -163,7 +163,7 @@ class Scene5100 : public Scene {
};
public:
SequenceManager _sequenceManager;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SpeakerMText _speakerMText;
SpeakerQText _speakerQText;
SpeakerSText _speakerSText;
@@ -226,7 +226,7 @@ class Scene5200 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SpeakerFLL _speakerFLL;
SpeakerFLText _speakerFLText;
SpeakerQL _speakerQL;
@@ -291,7 +291,7 @@ class Scene5300 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SequenceManager _sequenceManager;
SpeakerQR _speakerQR;
SpeakerQL _speakerQL;
diff --git a/engines/tsage/ringworld_scenes8.cpp b/engines/tsage/ringworld_scenes8.cpp
index 934c7494fa..2b329b958a 100644
--- a/engines/tsage/ringworld_scenes8.cpp
+++ b/engines/tsage/ringworld_scenes8.cpp
@@ -60,7 +60,7 @@ void Scene7000::Action1::signal() {
setAction(&scene->_action6, this);
break;
case 2:
- scene->_soundHandler.startSound(252);
+ scene->_soundHandler.play(252);
scene->_object8.remove();
scene->_object1.postInit();
scene->_object1.setVisage(7003);
@@ -184,7 +184,7 @@ void Scene7000::Action4::signal() {
setDelay(300);
break;
case 2:
- _globals->_soundHandler.startSound(252);
+ _globals->_soundHandler.play(252);
scene->_object1.show();
scene->_object1.setStrip(3);
scene->_object1.setFrame(1);
@@ -214,7 +214,7 @@ void Scene7000::Action5::signal() {
}
case 1:
_globals->_player.checkAngle(&scene->_object1);
- _globals->_soundHandler.startSound(252);
+ _globals->_soundHandler.play(252);
scene->_object1.setStrip(2);
scene->_stripManager.start(7015, this);
break;
@@ -546,7 +546,7 @@ void Scene7000::postInit(SceneObjectList *OwnerList) {
_object1.animate(ANIM_MODE_8, 0, NULL);
_globals->_sceneItems.push_back(&_object1);
}
- _soundHandler.startSound(251);
+ _soundHandler.play(251);
if (_globals->_sceneManager._previousScene == 2100) {
if (_globals->getFlag(72)) {
_globals->_player.postInit();
@@ -565,7 +565,7 @@ void Scene7000::postInit(SceneObjectList *OwnerList) {
setAction(&_action1);
}
} else {
- _globals->_soundHandler.startSound(250);
+ _globals->_soundHandler.play(250);
_globals->setFlag(72);
_object3.postInit();
@@ -611,9 +611,9 @@ void Scene7000::postInit(SceneObjectList *OwnerList) {
_object3.setVisage(5001);
_object3.setStrip2(1);
_object3.setPosition(Common::Point(307, 0));
- _soundHandler.startSound(151);
- _soundHandler.proc5(1);
- _globals->_soundHandler.startSound(250);
+ _soundHandler.play(151);
+ _soundHandler.holdAt(true);
+ _globals->_soundHandler.play(250);
setAction(&_action3);
}
@@ -1135,9 +1135,9 @@ void Scene7100::postInit(SceneObjectList *OwnerList) {
_object1.setPosition(Common::Point(100, 100));
setAction(&_action11);
- _soundHandler1.startSound(270);
- _soundHandler2.startSound(275);
- _globals->_soundHandler.startSound(270);
+ _soundHandler1.play(270);
+ _soundHandler2.play(275);
+ _globals->_soundHandler.play(270);
}
/*--------------------------------------------------------------------------
* Scene 7200 - Underwater: Entering the cave
@@ -1302,7 +1302,7 @@ void Scene7200::postInit(SceneObjectList *OwnerList) {
_swimmer.setPosition(Common::Point(-8, 16));
setAction(&_action1);
- _soundHandler.startSound(271);
+ _soundHandler.play(271);
}
/*--------------------------------------------------------------------------
@@ -1344,7 +1344,7 @@ void Scene7300::Action1::signal() {
break;
case 7:
setDelay(3);
- _globals->_soundHandler.proc1(NULL);
+ _globals->_soundHandler.fadeOut(NULL);
break;
case 8:
_globals->_sceneManager.changeScene(2280);
@@ -1497,7 +1497,7 @@ void Scene7300::postInit(SceneObjectList *OwnerList) {
_object8._numFrames = 2;
setAction(&_action1);
- _globals->_soundHandler.startSound(272);
+ _globals->_soundHandler.play(272);
}
/*--------------------------------------------------------------------------
@@ -1601,8 +1601,8 @@ void Scene7600::postInit(SceneObjectList *OwnerList) {
}
_sceneBounds.center(_globals->_player._position.x, _globals->_player._position.y);
loadScene(7600);
- _soundHandler2.startSound(255);
- _soundHandler1.startSound(251);
+ _soundHandler2.play(255);
+ _soundHandler1.play(251);
}
/*--------------------------------------------------------------------------
@@ -1665,7 +1665,7 @@ void Scene7700::Action3::signal() {
setDelay(60);
// No break on purpose!
case 2:
- scene->_soundHandler.startSound(260);
+ scene->_soundHandler.play(260);
scene->_object8.setVisage(7703);
scene->_object8.setPosition(Common::Point(177, 97));
scene->_object8.setStrip2(3);
@@ -1874,7 +1874,7 @@ void Scene7700::SceneHotspot8::doAction(int action) {
break;
case CURSOR_USE:
scene->_sceneMode = 7709;
- scene->_soundHandler.startSound(259);
+ scene->_soundHandler.play(259);
scene->_object15.setFrame(scene->_object15.getFrameCount());
scene->_object15.animate(ANIM_MODE_6, scene);
if ((scene->_field977 == 2) && (scene->_field97B == 0)) {
@@ -1900,7 +1900,7 @@ void Scene7700::SceneHotspot9::doAction(int action) {
break;
case CURSOR_USE:
scene->_sceneMode = 7709;
- scene->_soundHandler.startSound(259);
+ scene->_soundHandler.play(259);
scene->_object15.setFrame(1);
scene->_object15.animate(ANIM_MODE_5, scene);
if (scene->_field977 > 2) {
@@ -2034,7 +2034,7 @@ void Scene7700::Object7::doAction(int action) {
break;
case OBJECT_STUNNER:
if (!_globals->getFlag(78)) {
- _globals->_soundHandler.proc3();
+ _globals->_soundHandler.stop();
_globals->setFlag(78);
setAction(NULL);
_globals->_player.disableControl();
@@ -2124,7 +2124,8 @@ void Scene7700::Object9::doAction(int action) {
_globals->_sceneItems.push_front(&scene->_object10);
scene->_object10.fixPriority(240);
}
- scene->_soundHandler.startSound(262);
+
+ scene->_soundHandler.play(262);
scene->_object14.animate(ANIM_MODE_5, NULL);
}
_globals->_events.setCursor(CURSOR_WALK);
@@ -2222,7 +2223,7 @@ void Scene7700::signal() {
}
break;
case 7702:
- _soundHandler.proc1(0);
+ _soundHandler.fadeOut(0);
_globals->_sceneManager.changeScene(7600);
break;
case 7703:
@@ -2233,7 +2234,7 @@ void Scene7700::signal() {
_globals->_player.enableControl();
break;
case 7704:
- _globals->_soundHandler.startSound(256);
+ _globals->_soundHandler.play(256);
_prof.setStrip2(4);
_prof.setFrame2(1);
_prof.setPosition(Common::Point(159, 87));
@@ -2520,7 +2521,7 @@ void Scene7700::postInit(SceneObjectList *OwnerList) {
_sceneMode = 7701;
setAction(&_sequenceManager, this, 7701, &_globals->_player, NULL);
- _soundHandler.startSound(256);
+ _soundHandler.play(256);
}
Scene7700::Scene7700() {
diff --git a/engines/tsage/ringworld_scenes8.h b/engines/tsage/ringworld_scenes8.h
index 8b183e895f..fe9560d9d8 100644
--- a/engines/tsage/ringworld_scenes8.h
+++ b/engines/tsage/ringworld_scenes8.h
@@ -94,7 +94,7 @@ class Scene7000 : public Scene {
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SequenceManager _sequenceManager;
SpeakerSKText _speakerSKText;
SpeakerSKL _speakerSKL;
@@ -165,8 +165,8 @@ class Scene7100 : public Scene {
};
public:
- SoundHandler _soundHandler1;
- SoundHandler _soundHandler2;
+ ASound _soundHandler1;
+ ASound _soundHandler2;
SceneObject _object1;
SceneObject _object2;
SceneObject _object3;
@@ -230,7 +230,7 @@ public:
SceneObject _object7;
SceneObject _object8;
SceneObject _object9;
- SoundHandler _soundHandler;
+ ASound _soundHandler;
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
@@ -296,8 +296,8 @@ public:
SceneObject _object4;
SceneObject _object5;
SceneObject _object6;
- SoundHandler _soundHandler1;
- SoundHandler _soundHandler2;
+ ASound _soundHandler1;
+ ASound _soundHandler2;
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
@@ -409,7 +409,7 @@ class Scene7700 : public Scene {
virtual void doAction(int action);
};
public:
- SoundHandler _soundHandler;
+ ASound _soundHandler;
SequenceManager _sequenceManager;
GfxButton _gfxButton;
SpeakerEText _speakerEText;
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index 522e40c236..b184e59c9e 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -21,11 +21,13 @@
*/
#include "common/savefile.h"
+#include "common/mutex.h"
#include "graphics/palette.h"
#include "graphics/scaler.h"
#include "graphics/thumbnail.h"
#include "tsage/globals.h"
#include "tsage/saveload.h"
+#include "tsage/sound.h"
#include "tsage/tsage.h"
namespace tSage {
@@ -105,6 +107,7 @@ void Serializer::validate(int v, Common::Serializer::Version minVersion,
Common::Error Saver::save(int slot, const Common::String &saveName) {
assert(!getMacroRestoreFlag());
+ Common::StackLock slock1(_globals->_soundManager._serverDisabledMutex);
// Signal any objects registered for notification
_saveNotifiers.notify(false);
@@ -149,6 +152,7 @@ Common::Error Saver::save(int slot, const Common::String &saveName) {
Common::Error Saver::restore(int slot) {
assert(!getMacroRestoreFlag());
+ Common::StackLock slock1(_globals->_soundManager._serverDisabledMutex);
// Signal any objects registered for notification
_loadNotifiers.notify(false);
@@ -205,7 +209,7 @@ Common::Error Saver::restore(int slot) {
// Final post-restore notifications
_macroRestoreFlag = false;
- _loadNotifiers.notify(false);
+ _loadNotifiers.notify(true);
return Common::kNoError;
}
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index c1c2851f28..0382e4a1fc 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 5
+#define TSAGE_SAVEGAME_VERSION 6
class SavedObject;
diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp
index 4625661b62..18b3da2698 100644
--- a/engines/tsage/scenes.cpp
+++ b/engines/tsage/scenes.cpp
@@ -55,7 +55,7 @@ void SceneManager::checkScene() {
_nextSceneNumber = -1;
}
- Common::for_each(_globals->_sceneListeners.begin(), _globals->_sceneListeners.end(), SceneHandler::dispatchObject);
+ _globals->dispatchSounds();
}
void SceneManager::sceneChange() {
@@ -105,8 +105,6 @@ void SceneManager::sceneChange() {
// Set the next scene to be active
_sceneNumber = _nextSceneNumber;
- // TODO: Unknown check of word_45CD3 / call to saver method
-
// Free any regions
disposeRegions();
@@ -208,7 +206,6 @@ void SceneManager::setBackSurface() {
}
void SceneManager::saveListener(int saveMode) {
- warning("TODO: SceneManager::saveLIstener");
}
void SceneManager::loadNotifier(bool postFlag) {
@@ -238,7 +235,11 @@ void SceneManager::listenerSynchronize(Serializer &s) {
if (s.isLoading()) {
changeScene(_sceneNumber);
- checkScene();
+
+ if (_nextSceneNumber != -1) {
+ sceneChange();
+ _nextSceneNumber = -1;
+ }
}
_globals->_sceneManager._scrollerRect.synchronize(s);
diff --git a/engines/tsage/scenes.h b/engines/tsage/scenes.h
index b3c009c4fe..5845efaec9 100644
--- a/engines/tsage/scenes.h
+++ b/engines/tsage/scenes.h
@@ -71,7 +71,9 @@ public:
class SceneManager : public GameHandler, public SaveListener {
private:
- void disposeRegions() { warning("TODO: disposeRegions()"); }
+ void disposeRegions() {
+ // No need to do anything, since regions will be freed automatically when the scene is
+ }
Scene *getNewScene();
public:
Scene *_scene;
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index defec1cebd..01e770a77a 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -20,38 +20,3009 @@
*
*/
+#include "common/config-manager.h"
#include "tsage/core.h"
#include "tsage/globals.h"
#include "tsage/debugger.h"
#include "tsage/graphics.h"
+#include "tsage/tsage.h"
namespace tSage {
+static SoundManager *_soundManager = NULL;
+
+/*--------------------------------------------------------------------------*/
+
+SoundManager::SoundManager() {
+ _soundManager = this;
+ __sndmgrReady = false;
+ _ourSndResVersion = 0x102;
+ _ourDrvResVersion = 0x10A;
+
+ for (int i = 0; i < SOUND_ARR_SIZE; ++i)
+ _voiceTypeStructPtrs[i] = NULL;
+
+ _groupsAvail = 0;
+ _newVolume = _masterVol = 127;
+ _driversDetected = false;
+ _needToRethink = false;
+
+ _soTimeIndexFlag = false;
+}
+
+SoundManager::~SoundManager() {
+ if (__sndmgrReady) {
+ Common::StackLock slock(_serverDisabledMutex);
+
+ for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ) {
+ Sound *s = *i;
+ ++i;
+ s->stop();
+ }
+ for (Common::List<SoundDriver *>::iterator i = _installedDrivers.begin(); i != _installedDrivers.end(); ) {
+ SoundDriver *driver = *i;
+ ++i;
+ delete driver;
+ }
+ _sfTerminate();
+
+ g_system->getTimerManager()->removeTimerProc(_sfUpdateCallback);
+ }
+
+ _soundManager = NULL;
+}
+
void SoundManager::postInit() {
- _saver->addSaveNotifier(&SoundManager::saveNotifier);
- _saver->addLoadNotifier(&SoundManager::loadNotifier);
- _saver->addListener(this);
+ if (!__sndmgrReady) {
+ _saver->addSaveNotifier(&SoundManager::saveNotifier);
+ _saver->addLoadNotifier(&SoundManager::loadNotifier);
+ _saver->addListener(this);
+
+ // Install a timer for handling sound manager updates at 60Hz
+ g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / GAME_FRAME_RATE, NULL);
+
+ __sndmgrReady = true;
+ }
+}
+
+/**
+ * Loops through all the loaded sounds, and stops any that have been flagged for stopping
+ */
+void SoundManager::dispatch() {
+ Common::List<Sound *>::iterator i = _soundList.begin();
+ while (i != _soundList.end()) {
+ Sound *sound = *i;
+ ++i;
+
+ // If the sound is flagged for stopping, then stop it
+ if (sound->_stoppedAsynchronously) {
+ sound->stop();
+ }
+ }
+}
+
+void SoundManager::syncSounds() {
+ bool mute = false;
+ if (ConfMan.hasKey("mute"))
+ mute = ConfMan.getBool("mute");
+
+ bool music_mute = mute;
+
+ if (!mute) {
+ music_mute = ConfMan.getBool("music_mute");
+ }
+
+ // Get the new music volume
+ int musicVolume = music_mute ? 0 : MIN(255, ConfMan.getInt("music_volume"));
+
+ this->setMasterVol(musicVolume / 2);
+}
+
+void SoundManager::update() {
+ _sfSoundServer();
+}
+
+Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) {
+ assert(__sndmgrReady);
+ _availableDrivers.clear();
+
+ // Build up a list of available drivers. Currently we only implement an Adlib driver
+ SoundDriverEntry sd;
+ sd.driverNum = ADLIB_DRIVER_NUM;
+ sd.status = detectFlag ? SNDSTATUS_DETECTED : SNDSTATUS_SKIPPED;
+ sd.field2 = 0;
+ sd.field6 = 15000;
+ sd.shortDescription = "Adlib or SoundBlaster";
+ sd.longDescription = "3812fm";
+ _availableDrivers.push_back(sd);
+
+ _driversDetected = true;
+ return _availableDrivers;
+}
+
+void SoundManager::installConfigDrivers() {
+ installDriver(ADLIB_DRIVER_NUM);
+}
+
+Common::List<SoundDriverEntry> &SoundManager::getDriverList(bool detectFlag) {
+ if (detectFlag)
+ return _availableDrivers;
+ else
+ return buildDriverList(false);
+}
+
+void SoundManager::dumpDriverList() {
+ _availableDrivers.clear();
+}
+
+/**
+ * Install the specified driver number
+ */
+void SoundManager::installDriver(int driverNum) {
+ // If driver is already installed, no need to install it
+ if (isInstalled(driverNum))
+ return;
+
+ // Instantiate the sound driver
+ SoundDriver *driver = instantiateDriver(driverNum);
+ if (!driver)
+ return;
+
+ assert((_ourDrvResVersion >= driver->_minVersion) && (_ourDrvResVersion <= driver->_maxVersion));
+
+ // Mute any loaded sounds
+ Common::StackLock slock(_serverDisabledMutex);
+
+ for (Common::List<Sound *>::iterator i = _playList.begin(); i != _playList.end(); ++i)
+ (*i)->mute(true);
+
+ // Install the driver
+ if (!_sfInstallDriver(driver))
+ error("Sound driver initialization failed");
+
+ switch (driverNum) {
+ case ROLAND_DRIVER_NUM:
+ case ADLIB_DRIVER_NUM: {
+ // Handle loading bank infomation
+ byte *bankData = _resourceManager->getResource(RES_BANK, driverNum, 0, true);
+ if (bankData) {
+ // Install the patch bank data
+ _sfInstallPatchBank(driver, bankData);
+ DEALLOCATE(bankData);
+ } else {
+ // Could not locate patch bank data, so unload the driver
+ _sfUnInstallDriver(driver);
+
+ // Unmute currently active sounds
+ for (Common::List<Sound *>::iterator i = _playList.begin(); i != _playList.end(); ++i)
+ (*i)->mute(false);
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * Instantiate a driver class for the specified driver number
+ */
+SoundDriver *SoundManager::instantiateDriver(int driverNum) {
+ assert(driverNum == ADLIB_DRIVER_NUM);
+ return new AdlibSoundDriver();
+}
+
+/**
+ * Uninstall the specified driver
+ */
+void SoundManager::unInstallDriver(int driverNum) {
+ Common::List<SoundDriver *>::const_iterator i;
+ for (i = _installedDrivers.begin(); i != _installedDrivers.end(); ++i) {
+ if ((*i)->_driverResID == driverNum) {
+ // Found driver to remove
+
+ // Mute any loaded sounds
+ Common::StackLock slock(_serverDisabledMutex);
+
+ Common::List<Sound *>::iterator j;
+ for (j = _playList.begin(); j != _playList.end(); ++j)
+ (*j)->mute(true);
+
+ // Uninstall the driver
+ _sfUnInstallDriver(*i);
+
+ // Re-orient all the loaded sounds
+ for (j = _soundList.begin(); j != _soundList.end(); ++j)
+ (*j)->orientAfterDriverChange();
+
+ // Unmute currently active sounds
+ for (j = _playList.begin(); j != _playList.end(); ++j)
+ (*j)->mute(false);
+ }
+ }
+}
+
+/**
+ * Returns true if a specified driver number is currently installed
+ */
+bool SoundManager::isInstalled(int driverNum) const {
+ Common::List<SoundDriver *>::const_iterator i;
+ for (i = _installedDrivers.begin(); i != _installedDrivers.end(); ++i) {
+ if ((*i)->_driverResID == driverNum)
+ return true;
+ }
+
+ return false;
+}
+
+void SoundManager::setMasterVol(int volume) {
+ _newVolume = volume;
+}
+
+int SoundManager::getMasterVol() const {
+ return _masterVol;
+}
+
+void SoundManager::loadSound(int soundNum, bool showErrors) {
+ // This method preloaded the data associated with a given sound, so is now redundant
+}
+
+void SoundManager::unloadSound(int soundNum) {
+ // This method signalled the resource manager to unload the data for a sound, and is now redundant
+}
+
+int SoundManager::determineGroup(const byte *soundData) {
+ return _sfDetermineGroup(soundData);
+}
+
+void SoundManager::checkResVersion(const byte *soundData) {
+ int maxVersion = READ_LE_UINT16(soundData + 4);
+ int minVersion = READ_LE_UINT16(soundData + 6);
+
+ if (_soundManager->_ourSndResVersion < minVersion)
+ error("Attempt to play/prime sound resource that is too new");
+ if (_soundManager->_ourSndResVersion > maxVersion)
+ error("Attempt to play/prime sound resource that is too old");
+}
+
+int SoundManager::extractPriority(const byte *soundData) {
+ return READ_LE_UINT16(soundData + 12);
+}
+
+int SoundManager::extractLoop(const byte *soundData) {
+ return READ_LE_UINT16(soundData + 14);
+}
+
+void SoundManager::extractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum) {
+ _sfExtractTrackInfo(trackInfo, soundData, groupNum);
+}
+
+void SoundManager::addToSoundList(Sound *sound) {
+ if (!contains(_soundList, sound))
+ _soundList.push_back(sound);
+}
+
+void SoundManager::removeFromSoundList(Sound *sound) {
+ _soundList.remove(sound);
}
+void SoundManager::addToPlayList(Sound *sound) {
+ _sfAddToPlayList(sound);
+}
+
+void SoundManager::removeFromPlayList(Sound *sound) {
+ if (_soundManager)
+ _sfRemoveFromPlayList(sound);
+}
+
+bool SoundManager::isOnPlayList(Sound *sound) {
+ return _sfIsOnPlayList(sound);
+}
+
+void SoundManager::updateSoundVol(Sound *sound) {
+ _sfUpdateVolume(sound);
+}
+
+void SoundManager::updateSoundPri(Sound *sound) {
+ _sfUpdatePriority(sound);
+}
+
+void SoundManager::updateSoundLoop(Sound *sound) {
+ _sfUpdateLoop(sound);
+}
+
+void SoundManager::rethinkVoiceTypes() {
+ Common::StackLock slock(sfManager()._serverSuspendedMutex);
+ _sfRethinkVoiceTypes();
+}
+
+void SoundManager::_sfSoundServer() {
+ Common::StackLock slock1(sfManager()._serverDisabledMutex);
+ Common::StackLock slock2(sfManager()._serverSuspendedMutex);
+
+ if (sfManager()._needToRethink) {
+ _sfRethinkVoiceTypes();
+ sfManager()._needToRethink = false;
+ } else {
+ _sfDereferenceAll();
+ }
+
+ // If the master volume has changed, update it
+ if (sfManager()._newVolume != sfManager()._masterVol)
+ _sfSetMasterVol(sfManager()._newVolume);
+
+ // If a time index has been set for any sound, fast forward to it
+ SynchronizedList<Sound *>::iterator i;
+ for (i = sfManager()._playList.begin(); i != sfManager()._playList.end(); ++i) {
+ Sound *s = *i;
+ if (s->_newTimeIndex != 0) {
+ s->mute(true);
+ s->_soSetTimeIndex(s->_newTimeIndex);
+ s->mute(false);
+ s->_newTimeIndex = 0;
+ }
+ }
+
+ // Handle any fading if necessary
+ _sfProcessFading();
+
+ // Poll all sound drivers in case they need it
+ for (Common::List<SoundDriver *>::iterator j = sfManager()._installedDrivers.begin();
+ j != sfManager()._installedDrivers.end(); ++j) {
+ (*j)->poll();
+ }
+}
+
+void SoundManager::_sfProcessFading() {
+ // Loop through processing active sounds
+ bool removeFlag = false;
+ Common::List<Sound *>::iterator i = sfManager()._playList.begin();
+ while (i != sfManager()._playList.end()) {
+ Sound *s = *i;
+ ++i;
+
+ if (!s->_pausedCount)
+ removeFlag = s->_soServiceTracks();
+ if (removeFlag) {
+ _sfDoRemoveFromPlayList(s);
+ s->_stoppedAsynchronously = true;
+ sfManager()._needToRethink = true;
+ }
+
+ if (s->_fadeDest != -1) {
+ if (s->_fadeCounter != 0)
+ --s->_fadeCounter;
+ else {
+ if (s->_volume >= s->_fadeDest) {
+ s->_volume = ((s->_volume - s->_fadeDest) > s->_fadeSteps) ?
+ s->_volume - s->_fadeSteps : s->_fadeDest;
+ } else {
+ s->_volume = ((s->_fadeDest - s->_volume) > s->_fadeSteps) ?
+ s->_volume + s->_fadeSteps : s->_fadeDest;
+ }
+
+ _sfDoUpdateVolume(s);
+ if (s->_volume != s->_fadeDest)
+ s->_fadeCounter = s->_fadeTicks;
+ else {
+ s->_fadeDest = -1;
+ if (s->_stopAfterFadeFlag) {
+ _sfDoRemoveFromPlayList(s);
+ s->_stoppedAsynchronously = true;
+ sfManager()._needToRethink = true;
+ }
+ }
+ }
+ }
+ }
+
+ // Loop through the voiceType list
+ for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
+ VoiceTypeStruct *vtStruct = sfManager()._voiceTypeStructPtrs[voiceIndex];
+ if (!vtStruct)
+ continue;
+
+ if (vtStruct->_voiceType == VOICETYPE_1) {
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if (vtStruct->_entries[idx]._type1._field6 >= -1)
+ ++vtStruct->_entries[idx]._type1._field6;
+ }
+ }
+ }
+}
+
+void SoundManager::_sfUpdateVoiceStructs() {
+ for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
+ VoiceTypeStruct *vs = sfManager()._voiceTypeStructPtrs[voiceIndex];
+ if (!vs)
+ continue;
+
+ if (vs->_voiceType == VOICETYPE_0) {
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntry &vse = vs->_entries[idx];
+
+ vse._type0._sound = vse._type0._sound2;
+ vse._type0._channelNum = vse._type0._channelNum2;
+ vse._type0._priority = vse._type0._priority2;
+ vse._type0._fieldA = vse._type0._field12;
+ }
+ } else {
+ vs->_field3 = vs->_numVoices;
+
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntry &vse = vs->_entries[idx];
+
+ vse._type1._sound = vse._type1._sound2;
+ vse._type1._channelNum = vse._type1._channelNum2;
+ vse._type1._priority = vse._type1._priority2;
+ }
+ }
+ }
+}
+
+void SoundManager::_sfUpdateVoiceStructs2() {
+ for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
+ VoiceTypeStruct *vtStruct = sfManager()._voiceTypeStructPtrs[voiceIndex];
+ if (!vtStruct)
+ continue;
+
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+
+ if (vtStruct->_voiceType == VOICETYPE_0) {
+ VoiceStructEntryType0 &vse = vtStruct->_entries[idx]._type0;
+ vse._sound2 = vse._sound;
+ vse._channelNum2 = vse._channelNum;
+ vse._priority2 = vse._priority;
+ vse._field12 = vse._fieldA;
+ } else {
+ VoiceStructEntryType1 &vse = vtStruct->_entries[idx]._type1;
+ vse._sound2 = vse._sound;
+ vse._channelNum2 = vse._channelNum;
+ vse._priority2 = vse._priority;
+ }
+ }
+ }
+}
+
+void SoundManager::_sfUpdateCallback(void *ref) {
+ ((SoundManager *)ref)->update();
+}
+
+/*--------------------------------------------------------------------------*/
+
void SoundManager::saveNotifier(bool postFlag) {
- _globals->_soundManager.saveNotifierProc(postFlag);
+ _soundManager->saveNotifierProc(postFlag);
}
void SoundManager::saveNotifierProc(bool postFlag) {
- warning("TODO: SoundManager::saveNotifierProc");
+ // Nothing needs to be done when saving the game
}
void SoundManager::loadNotifier(bool postFlag) {
- _globals->_soundManager.loadNotifierProc(postFlag);
+ _soundManager->loadNotifierProc(postFlag);
}
void SoundManager::loadNotifierProc(bool postFlag) {
- warning("TODO: SoundManager::loadNotifierProc");
+ if (!postFlag) {
+ // Stop any currently playing sounds
+ if (__sndmgrReady) {
+ Common::StackLock slock(_serverDisabledMutex);
+
+ for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ) {
+ Sound *s = *i;
+ ++i;
+ s->stop();
+ }
+ }
+ } else {
+ // Savegame is now loaded, so iterate over the sound list to prime any sounds as necessary
+ for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+ Sound *s = *i;
+ s->orientAfterRestore();
+ }
+ }
}
void SoundManager::listenerSynchronize(Serializer &s) {
s.validate("SoundManager");
- warning("TODO: SoundManager listenerSynchronize");
+ assert(__sndmgrReady && _driversDetected);
+
+ if (s.getVersion() < 6)
+ return;
+
+ Common::StackLock slock(_serverDisabledMutex);
+ _playList.synchronize(s);
+
+ _soundList.synchronize(s);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SoundManager &SoundManager::sfManager() {
+ assert(_soundManager);
+ return *_soundManager;
+}
+
+int SoundManager::_sfDetermineGroup(const byte *soundData) {
+ const byte *p = soundData + READ_LE_UINT16(soundData + 8);
+ uint32 v;
+ while ((v = READ_LE_UINT32(p)) != 0) {
+ if ((v & _soundManager->_groupsAvail) == v)
+ return v;
+
+ p += 6 + (READ_LE_UINT16(p + 4) * 4);
+ }
+
+ return 0;
+}
+
+void SoundManager::_sfAddToPlayList(Sound *sound) {
+ Common::StackLock slock(sfManager()._serverSuspendedMutex);
+
+ _sfDoAddToPlayList(sound);
+ sound->_stoppedAsynchronously = false;
+ _sfRethinkVoiceTypes();
+}
+
+void SoundManager::_sfRemoveFromPlayList(Sound *sound) {
+ Common::StackLock slock(sfManager()._serverSuspendedMutex);
+
+ if (_sfDoRemoveFromPlayList(sound))
+ _sfRethinkVoiceTypes();
+}
+
+bool SoundManager::_sfIsOnPlayList(Sound *sound) {
+ Common::StackLock slock(sfManager()._serverSuspendedMutex);
+
+ bool result = contains(_soundManager->_playList, sound);
+
+ return result;
+}
+
+void SoundManager::_sfRethinkSoundDrivers() {
+ // Free any existing entries
+ int idx;
+
+ for (idx = 0; idx < SOUND_ARR_SIZE; ++idx) {
+ if (sfManager()._voiceTypeStructPtrs[idx]) {
+ delete sfManager()._voiceTypeStructPtrs[idx];
+ sfManager()._voiceTypeStructPtrs[idx] = NULL;
+ }
+ }
+
+ for (idx = 0; idx < SOUND_ARR_SIZE; ++idx) {
+ byte flag = 0xff;
+ int total = 0;
+
+ // Loop through the sound drivers
+ for (Common::List<SoundDriver *>::iterator i = sfManager()._installedDrivers.begin();
+ i != sfManager()._installedDrivers.end(); ++i) {
+ // Process the group data for each sound driver
+ SoundDriver *driver = *i;
+ const byte *groupData = driver->_groupOffset->pData;
+
+ while (*groupData != 0xff) {
+ byte byteVal = *groupData++;
+
+ if (byteVal == idx) {
+ byte byteVal2 = *groupData++;
+ if (flag == 0xff)
+ flag = byteVal2;
+ else {
+ assert(flag == byteVal2);
+ }
+
+ if (!flag) {
+ while (*groupData++ != 0xff)
+ ++total;
+ } else {
+ total += *groupData;
+ groupData += 2;
+ }
+ } else if (*groupData++ == 0) {
+ while (*groupData != 0xff)
+ ++groupData;
+ ++groupData;
+ } else {
+ groupData += 2;
+ }
+ }
+ }
+
+ if (total) {
+ VoiceTypeStruct *vs = new VoiceTypeStruct();
+ sfManager()._voiceTypeStructPtrs[idx] = vs;
+
+ if (!flag) {
+ vs->_voiceType = VOICETYPE_0;
+ } else {
+ vs->_voiceType = VOICETYPE_1;
+ }
+
+ vs->_total = vs->_numVoices = total;
+ vs->_field3 = 0;
+
+ for (Common::List<SoundDriver *>::iterator i = sfManager()._installedDrivers.begin();
+ i != sfManager()._installedDrivers.end(); ++i) {
+ // Process the group data for each sound driver
+ SoundDriver *driver = *i;
+ const byte *groupData = driver->_groupOffset->pData;
+
+ while (*groupData != 0xff) {
+ byte byteVal = *groupData++;
+
+ if (byteVal == idx) {
+ ++groupData;
+
+ if (!flag) {
+ while ((byteVal = *groupData++) != 0xff) {
+ VoiceStructEntry ve;
+ memset(&ve, 0, sizeof(VoiceStructEntry));
+
+ ve._field1 = (byteVal & 0x80) ? 0 : 1;
+ ve._driver = driver;
+ ve._type0._sound = NULL;
+ ve._type0._channelNum = 0;
+ ve._type0._priority = 0;
+ ve._type0._fieldA = 0;
+
+ vs->_entries.push_back(ve);
+ }
+ } else {
+ byteVal = *groupData;
+ groupData += 2;
+
+ for (int entryIndez = 0; entryIndez < byteVal; ++entryIndez) {
+ VoiceStructEntry ve;
+ memset(&ve, 0, sizeof(VoiceStructEntry));
+
+ ve._voiceNum = entryIndez;
+ ve._driver = driver;
+ ve._type1._field4 = -1;
+ ve._type1._field5 = 0;
+ ve._type1._field6 = 0;
+ ve._type1._sound = NULL;
+ ve._type1._channelNum = 0;
+ ve._type1._priority = 0;
+
+ vs->_entries.push_back(ve);
+ }
+ }
+ } else {
+ if (*groupData++ != 0) {
+ while (*groupData != 0xff)
+ ++groupData;
+ } else {
+ groupData += 2;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void SoundManager::_sfRethinkVoiceTypes() {
+ _sfDereferenceAll();
+
+ // Pre-processing
+ for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
+ VoiceTypeStruct *vs = sfManager()._voiceTypeStructPtrs[voiceIndex];
+ if (!vs)
+ continue;
+
+ if (vs->_voiceType == VOICETYPE_0) {
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntry &vse = vs->_entries[idx];
+ vse._type0._sound3 = vse._type0._sound;
+ vse._type0._channelNum3 = vse._type0._channelNum;
+ vse._type0._priority3 = vse._type0._priority;
+ vse._type0._field1A = vse._type0._fieldA;
+ vse._type0._sound = NULL;
+ vse._type0._channelNum = 0;
+ vse._type0._priority = 0;
+ vse._type0._fieldA = 0;
+ vse._type0._sound2 = NULL;
+ vse._type0._channelNum2 = 0;
+ vse._type0._priority2 = 0;
+ vse._type0._field12 = 0;
+ }
+ } else {
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntry &vse = vs->_entries[idx];
+ vse._type1._sound3 = vse._type1._sound;
+ vse._type1._channelNum3 = vse._type1._channelNum;
+ vse._type1._priority3 = vse._type1._priority;
+ vse._type1._sound = NULL;
+ vse._type1._channelNum = 0;
+ vse._type1._priority = 0;
+ vse._type1._sound2 = NULL;
+ vse._type1._channelNum2 = 0;
+ vse._type1._priority2 = 0;
+ }
+
+ // Reset the number of voices available
+ vs->_numVoices = vs->_total;
+ }
+ }
+
+ // Main processing loop
+ int priorityOffset = 0;
+ for (Common::List<Sound *>::iterator i = sfManager()._playList.begin(); i != sfManager()._playList.end(); ++i, priorityOffset += 16) {
+ Sound *sound = *i;
+ if ((sound->_mutedCount != 0) || (sound->_pausedCount != 0))
+ continue;
+
+ _sfUpdateVoiceStructs();
+ Common::set_to(sound->_chWork, sound->_chWork + SOUND_ARR_SIZE, false);
+
+ for (;;) {
+ // Scan for sub priority
+ int foundIndex = -1, foundPriority = 0;
+ for (int idx = 0; idx < SOUND_ARR_SIZE; ++idx) {
+ if (!(sound->_chFlags[idx] & 0x8000) & !sound->_chWork[idx]) {
+ int subPriority = sound->_chSubPriority[idx];
+ if (subPriority)
+ subPriority = 16 - subPriority + priorityOffset;
+
+ if (foundIndex != -1) {
+ if (subPriority < foundPriority) {
+ foundIndex = idx;
+ foundPriority = subPriority;
+ }
+ } else {
+ foundIndex = idx;
+ foundPriority = subPriority;
+ }
+ }
+ }
+ if (foundIndex == -1)
+ break;
+
+ int chNumVoices = sound->_chNumVoices[foundIndex];
+ sound->_chWork[foundIndex] = true;
+
+ VoiceTypeStruct *vtStruct = sfManager()._voiceTypeStructPtrs[sound->_chVoiceType[foundIndex]];
+ if (!vtStruct) {
+ if (foundPriority)
+ continue;
+
+ _sfUpdateVoiceStructs2();
+ break;
+ }
+
+ if (vtStruct->_voiceType != VOICETYPE_0) {
+ // Type 1
+ int numVoices = vtStruct->_numVoices;
+
+ if (numVoices >= chNumVoices) {
+ int channelCount = chNumVoices, idx = 0;
+ while (channelCount > 0) {
+ if (!vtStruct->_entries[idx]._type1._sound2) {
+ vtStruct->_entries[idx]._type1._sound2 = sound;
+ vtStruct->_entries[idx]._type1._channelNum2 = foundIndex;
+ vtStruct->_entries[idx]._type1._priority2 = foundPriority;
+ --channelCount;
+ }
+ ++idx;
+ }
+
+ vtStruct->_numVoices -= chNumVoices;
+ continue;
+ } else if (!foundPriority) {
+ do {
+ int maxPriority = 0;
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx)
+ maxPriority = MAX(maxPriority, vtStruct->_entries[idx]._type1._priority2);
+
+ if (!maxPriority) {
+ _sfUpdateVoiceStructs2();
+ break;
+ }
+
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if (vtStruct->_entries[idx]._type1._priority2 == maxPriority) {
+ vtStruct->_entries[idx]._type1._sound2 = NULL;
+ vtStruct->_entries[idx]._type1._channelNum2 = 0;
+ vtStruct->_entries[idx]._type1._priority2 = 0;
+ ++numVoices;
+ }
+ }
+ } while (chNumVoices > numVoices);
+
+ int voicesCtr = chNumVoices;
+ for (uint idx = 0; (idx < vtStruct->_entries.size()) && (voicesCtr > 0); ++idx) {
+ if (!vtStruct->_entries[idx]._type1._sound2) {
+ vtStruct->_entries[idx]._type1._sound2 = sound;
+ vtStruct->_entries[idx]._type1._channelNum2 = foundIndex;
+ vtStruct->_entries[idx]._type1._priority2 = foundPriority;
+ --voicesCtr;
+ }
+ }
+
+ numVoices -= chNumVoices;
+ vtStruct->_numVoices = numVoices;
+ continue;
+ } else if (!numVoices) {
+ break;
+ }
+ continue;
+ } else {
+ // Type 0
+ if (sound->_isEmpty) {
+ uint idx = 0;
+ while ((idx < vtStruct->_entries.size()) &&
+ (vtStruct->_entries[idx]._voiceNum == foundIndex))
+ ++idx;
+ if (idx == vtStruct->_entries.size())
+ continue;
+ }
+
+ int flagsVal = sound->_chFlags[foundIndex] & 3;
+ if (flagsVal != 1) {
+ // All modes except mode 1 (loc_23EDF)
+ int entryIndex = -1, maxVoiceNum = 0;
+
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if (!vtStruct->_entries[idx]._type0._sound2 && (vtStruct->_entries[idx]._field1 != 0) &&
+ (vtStruct->_entries[idx]._voiceNum > maxVoiceNum)) {
+ maxVoiceNum = vtStruct->_entries[idx]._voiceNum;
+ entryIndex = idx;
+ }
+ }
+
+ if (entryIndex != -1) {
+ vtStruct->_entries[entryIndex]._type0._sound2 = sound;
+ vtStruct->_entries[entryIndex]._type0._channelNum2 = foundIndex;
+ vtStruct->_entries[entryIndex]._type0._priority2 = foundPriority;
+ vtStruct->_entries[entryIndex]._type0._field12 = 0;
+ continue;
+ }
+
+ if (foundPriority != 0)
+ continue;
+
+ int maxPriority = 0;
+ entryIndex = -1;
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if ((vtStruct->_entries[idx]._field1 != 0) &&
+ (vtStruct->_entries[idx]._type0._priority2 > maxPriority)) {
+ maxPriority = vtStruct->_entries[idx]._type0._priority2;
+ entryIndex = idx;
+ }
+ }
+
+ if (entryIndex != -1) {
+ vtStruct->_entries[entryIndex]._type0._sound2 = sound;
+ vtStruct->_entries[entryIndex]._type0._channelNum2 = foundIndex;
+ vtStruct->_entries[entryIndex]._type0._priority2 = foundPriority;
+ vtStruct->_entries[entryIndex]._type0._field12 = 0;
+ continue;
+ }
+
+ _sfUpdateVoiceStructs2();
+ break;
+ } else {
+ // Channel mode 1 handling (loc_23FAC)
+
+ bool foundMatch = false;
+ int entryIndex = -1;
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if (vtStruct->_entries[idx]._voiceNum == foundIndex) {
+ foundIndex = true;
+ if (!vtStruct->_entries[idx]._type0._sound2) {
+ entryIndex = idx;
+ break;
+ }
+ }
+ }
+
+ if (entryIndex != -1) {
+ vtStruct->_entries[entryIndex]._type0._sound2 = sound;
+ vtStruct->_entries[entryIndex]._type0._channelNum2 = foundIndex;
+ vtStruct->_entries[entryIndex]._type0._priority2 = foundPriority;
+ vtStruct->_entries[entryIndex]._type0._field12 = 0;
+ continue;
+ }
+
+ if (!foundMatch) {
+ if (foundPriority)
+ continue;
+ if (entryIndex == -1) {
+ _sfUpdateVoiceStructs2();
+ break;
+ }
+ }
+
+ // Find the entry with the highest priority
+ int maxPriority = 0;
+ foundMatch = false;
+ entryIndex = -1;
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if (vtStruct->_entries[idx]._voiceNum != foundIndex)
+ continue;
+ if (!vtStruct->_entries[idx]._type0._field12) {
+ foundMatch = true;
+ break;
+ }
+
+ if (vtStruct->_entries[idx]._type0._priority2 > maxPriority) {
+ maxPriority = vtStruct->_entries[idx]._type0._priority2;
+ entryIndex = -1;
+ }
+ }
+
+ if (!foundMatch) {
+ if (foundPriority)
+ continue;
+
+ if (entryIndex != -1) {
+ vtStruct->_entries[entryIndex]._type0._sound2 = sound;
+ vtStruct->_entries[entryIndex]._type0._channelNum2 = foundIndex;
+ vtStruct->_entries[entryIndex]._type0._priority2 = foundPriority;
+ vtStruct->_entries[entryIndex]._type0._field12 = 1;
+ continue;
+ }
+
+ _sfUpdateVoiceStructs2();
+ break;
+ }
+
+ // Found a match (loc_24061)
+ maxPriority = 0;
+ int maxVoiceNum = 0;
+ int priorityIndex = -1, voiceIndex = -1;
+
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if (vtStruct->_entries[idx]._field1) {
+ if (!vtStruct->_entries[idx]._type0._sound2) {
+ if (vtStruct->_entries[idx]._voiceNum > maxVoiceNum) {
+ maxVoiceNum = vtStruct->_entries[idx]._voiceNum;
+ voiceIndex = idx;
+ }
+ } else {
+ if (vtStruct->_entries[idx]._type0._priority2 > maxPriority) {
+ maxPriority = vtStruct->_entries[idx]._type0._priority2;
+ priorityIndex = idx;
+ }
+ }
+ }
+ }
+
+ if (voiceIndex != -1) {
+ VoiceStructEntryType0 &vteSrc = vtStruct->_entries[foundIndex]._type0;
+ VoiceStructEntryType0 &vteDest = vtStruct->_entries[voiceIndex]._type0;
+
+ vteDest._sound2 = vteSrc._sound2;
+ vteDest._channelNum2 = vteSrc._channelNum2;
+ vteDest._priority2 = vteSrc._priority2;
+
+ vteSrc._sound2 = sound;
+ vteSrc._channelNum2 = foundIndex;
+ vteSrc._priority2 = foundPriority;
+ vteSrc._field12 = 1;
+ continue;
+ }
+
+ if (!foundPriority)
+ continue;
+ if (priorityIndex == -1) {
+ _sfUpdateVoiceStructs2();
+ break;
+ }
+
+ VoiceStructEntryType0 &vteSrc = vtStruct->_entries[foundIndex]._type0;
+ VoiceStructEntryType0 &vteDest = vtStruct->_entries[priorityIndex]._type0;
+
+ if (priorityIndex != foundIndex) {
+ vteDest._sound2 = vteSrc._sound2;
+ vteDest._channelNum2 = vteSrc._channelNum2;
+ vteDest._priority2 = vteSrc._priority2;
+ vteDest._field12 = vteSrc._field12;
+ }
+
+ vteSrc._sound2 = sound;
+ vteSrc._channelNum2 = foundIndex;
+ vteSrc._priority2 = foundPriority;
+ vteSrc._field12 = 1;
+ continue;
+ }
+ }
+ }
+ }
+
+ // Post-processing
+ for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
+ VoiceTypeStruct *vs = sfManager()._voiceTypeStructPtrs[voiceIndex];
+ if (!vs)
+ continue;
+
+ if (vs->_voiceType == VOICETYPE_0) {
+ // Type 0
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntryType0 &vse = vs->_entries[idx]._type0;
+ SoundDriver *driver = vs->_entries[idx]._driver;
+ assert(driver);
+
+ if (vse._field12) {
+ int total = 0;
+ vse._sound = vse._sound2;
+ if (vse._sound3 != vse._sound)
+ ++total;
+
+ vse._channelNum = vse._channelNum2;
+ if (vse._channelNum3 != vse._channelNum)
+ ++total;
+
+ vse._priority = vse._priority2;
+ vse._fieldA = 1;
+ vse._sound2 = NULL;
+
+ if (total) {
+ driver->proc24(vse._channelNum, idx, vse._sound, 123, 0);
+ driver->proc24(vse._channelNum, idx, vse._sound, 1, vse._sound->_chModulation[vse._channelNum]);
+ driver->proc24(vse._channelNum, idx, vse._sound, 7,
+ vse._sound->_chVolume[vse._channelNum] * vse._sound->_volume / 127);
+ driver->proc24(vse._channelNum, idx, vse._sound, 10, vse._sound->_chPan[vse._channelNum]);
+ driver->proc24(vse._channelNum, idx, vse._sound, 64, vse._sound->_chDamper[vse._channelNum]);
+
+ driver->setProgram(vse._channelNum, vse._sound->_chProgram[vse._channelNum]);
+ driver->setPitchBlend(vse._channelNum, vse._sound->_chPitchBlend[vse._channelNum]);
+
+ vse._sound3 = NULL;
+ }
+ } else {
+ vse._sound = NULL;
+ vse._channelNum = 0;
+ vse._priority = 0;
+ vse._fieldA = 0;
+ }
+ }
+
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntryType0 &vse = vs->_entries[idx]._type0;
+ Sound *sound = vse._sound2;
+ int channelNum = vse._channelNum2;
+
+ if (!sound)
+ continue;
+
+ for (uint entryIndex = 0; entryIndex < vs->_entries.size(); ++entryIndex) {
+ if ((vs->_entries[entryIndex]._type0._sound3 != sound) ||
+ (vs->_entries[entryIndex]._type0._channelNum3 != channelNum)) {
+ // Found match
+ vs->_entries[entryIndex]._type0._sound = sound;
+ vs->_entries[entryIndex]._type0._channelNum = channelNum;
+ vs->_entries[entryIndex]._type0._priority = vse._priority2;
+ vs->_entries[entryIndex]._type0._fieldA = 0;
+ vse._sound2 = NULL;
+ break;
+ }
+ }
+ }
+
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntryType0 &vse = vs->_entries[idx]._type0;
+ Sound *sound = vse._sound2;
+ if (!sound)
+ continue;
+
+ int voiceNum = 0, foundIndex = -1;
+ for (uint entryIndex = 0; entryIndex < vs->_entries.size(); ++entryIndex) {
+ if ((vs->_entries[entryIndex]._field1) && !vs->_entries[entryIndex]._type0._sound) {
+ int tempVoice = vs->_entries[entryIndex]._voiceNum;
+
+ if (voiceNum <= tempVoice) {
+ voiceNum = tempVoice;
+ foundIndex = entryIndex;
+ }
+ }
+ }
+ assert(foundIndex != -1);
+
+ VoiceStructEntryType0 &vseFound = vs->_entries[foundIndex]._type0;
+
+ vseFound._sound = vse._sound2;
+ vseFound._channelNum = vse._channelNum2;
+ vseFound._priority = vse._priority2;
+ vseFound._fieldA = 0;
+
+ SoundDriver *driver = vs->_entries[foundIndex]._driver;
+ assert(driver);
+
+ driver->proc24(vseFound._channelNum, voiceIndex, vseFound._sound, 123, 0);
+ driver->proc24(vseFound._channelNum, voiceIndex, vseFound._sound,
+ 1, vseFound._sound->_chModulation[vseFound._channelNum]);
+ driver->proc24(vseFound._channelNum, voiceIndex, vseFound._sound,
+ 7, vseFound._sound->_chVolume[vseFound._channelNum] * vseFound._sound->_volume / 127);
+ driver->proc24(vseFound._channelNum, voiceIndex, vseFound._sound,
+ 10, vseFound._sound->_chPan[vseFound._channelNum]);
+ driver->setProgram(vseFound._channelNum, vseFound._sound->_chProgram[vseFound._channelNum]);
+ driver->setPitchBlend(vseFound._channelNum, vseFound._sound->_chPitchBlend[vseFound._channelNum]);
+ }
+
+ // Final loop
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntryType0 &vse = vs->_entries[idx]._type0;
+
+ if (!vse._sound && (vse._sound3)) {
+ SoundDriver *driver = vs->_entries[idx]._driver;
+ assert(driver);
+ driver->proc24(vs->_entries[idx]._voiceNum, voiceIndex, vse._sound3, 123, 0);
+ }
+ }
+
+ } else {
+ // Type 1
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntry &vse = vs->_entries[idx];
+ vse._type1._sound = NULL;
+ vse._type1._channelNum = 0;
+ vse._type1._priority = 0;
+ }
+
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntryType1 &vse = vs->_entries[idx]._type1;
+ Sound *sound = vse._sound2;
+ int channelNum = vse._channelNum2;
+
+ if (!sound)
+ continue;
+
+ for (uint entryIndex = 0; entryIndex < vs->_entries.size(); ++entryIndex) {
+ VoiceStructEntryType1 &vse2 = vs->_entries[entryIndex]._type1;
+ if (!vse2._sound && (vse2._sound3 == sound) && (vse2._channelNum3 == channelNum)) {
+ vse2._sound = sound;
+ vse2._channelNum = channelNum;
+ vse2._priority = vse._priority2;
+ vse._sound2 = NULL;
+ break;
+ }
+ }
+ }
+
+ uint idx2 = 0;
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntryType1 &vse = vs->_entries[idx]._type1;
+ Sound *sound = vse._sound2;
+ if (!sound)
+ continue;
+
+ while (vs->_entries[idx2]._type1._sound)
+ ++idx2;
+
+ VoiceStructEntryType1 &vse2 = vs->_entries[idx2]._type1;
+ vse2._sound = vse._sound2;
+ vse2._channelNum = vse._channelNum2;
+ vse2._priority = vse._priority2;
+ vse2._field4 = -1;
+ vse2._field5 = 0;
+ vse2._field6 = 0;
+
+ SoundDriver *driver = vs->_entries[idx2]._driver;
+ assert(driver);
+
+ driver->updateVoice(vs->_entries[idx2]._voiceNum);
+ driver->proc38(vs->_entries[idx2]._voiceNum, 1, vse2._sound->_chModulation[vse2._channelNum]);
+ driver->proc38(vs->_entries[idx2]._voiceNum, 7,
+ vse2._sound->_chVolume[vse2._channelNum] * vse2._sound->_volume / 127);
+ driver->proc38(vs->_entries[idx2]._voiceNum, 10, vse2._sound->_chPan[vse2._channelNum]);
+ driver->setPitch(vs->_entries[idx2]._voiceNum, vse2._sound->_chPitchBlend[vse2._channelNum]);
+ }
+
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntryType1 &vse = vs->_entries[idx]._type1;
+
+ if (!vse._sound && (vse._sound3)) {
+ vse._field4 = -1;
+ vse._field5 = 0;
+ vse._field6 = 0;
+
+ SoundDriver *driver = vs->_entries[idx]._driver;
+ assert(driver);
+ driver->updateVoice(vs->_entries[idx]._voiceNum);
+ }
+ }
+ }
+ }
+}
+
+void SoundManager::_sfUpdateVolume(Sound *sound) {
+ _sfDereferenceAll();
+ _sfDoUpdateVolume(sound);
+}
+
+void SoundManager::_sfDereferenceAll() {
+ // Orignal used handles for both the driver list and voiceTypeStructPtrs list. This method then refreshed
+ // pointer lists based on the handles. Since in ScummVM we're just using pointers directly, this
+ // method doesn't need any implementation
+}
+
+void SoundManager::_sfUpdatePriority(Sound *sound) {
+ Common::StackLock slock(sfManager()._serverSuspendedMutex);
+
+ int tempPriority = (sound->_fixedPriority == 255) ? sound->_sndResPriority : sound->_priority;
+ if (sound->_priority != tempPriority) {
+ sound->_priority = tempPriority;
+ if (_sfDoRemoveFromPlayList(sound)) {
+ _sfDoAddToPlayList(sound);
+ _sfRethinkVoiceTypes();
+ }
+ }
+}
+
+void SoundManager::_sfUpdateLoop(Sound *sound) {
+ if (sound->_fixedLoop)
+ sound->_loop = sound->_sndResLoop;
+ else
+ sound->_loop = sound->_fixedLoop;
+}
+
+void SoundManager::_sfSetMasterVol(int volume) {
+ if (volume > 127)
+ volume = 127;
+
+ if (volume != _soundManager->_masterVol) {
+ _soundManager->_masterVol = volume;
+
+ for (Common::List<SoundDriver *>::iterator i = _soundManager->_installedDrivers.begin();
+ i != _soundManager->_installedDrivers.end(); ++i) {
+ (*i)->setMasterVolume(volume);
+ }
+ }
+}
+
+void SoundManager::_sfExtractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum) {
+ trackInfo->_numTracks = 0;
+
+ const byte *p = soundData + READ_LE_UINT16(soundData + 8);
+ uint32 v;
+ while ((v = READ_LE_UINT32(p)) != 0) {
+ if ((v == 0x80000000) || (v == (uint)groupNum)) {
+ // Found group to process
+ int count = READ_LE_UINT16(p + 4);
+ p += 6;
+
+ for (int idx = 0; idx < count; ++idx) {
+ if (trackInfo->_numTracks == 16) {
+ trackInfo->_numTracks = -1;
+ return;
+ }
+
+ trackInfo->_chunks[trackInfo->_numTracks] = READ_LE_UINT16(p);
+ trackInfo->_voiceTypes[trackInfo->_numTracks] = READ_LE_UINT16(p + 2);
+ ++trackInfo->_numTracks;
+ p += 4;
+ }
+ } else {
+ // Not correct group, so move to next one
+ p += 6 + (READ_LE_UINT16(p + 4) * 4);
+ }
+ }
+}
+
+void SoundManager::_sfTerminate() {
+
+}
+
+void SoundManager::_sfExtractGroupMask() {
+ uint32 mask = 0;
+
+ for (Common::List<SoundDriver *>::iterator i = sfManager()._installedDrivers.begin();
+ i != sfManager()._installedDrivers.end(); ++i)
+ mask |= (*i)->_groupMask;
+
+ _soundManager->_groupsAvail = mask;
+}
+
+bool SoundManager::_sfInstallDriver(SoundDriver *driver) {
+ if (!driver->open())
+ return false;
+
+ sfManager()._installedDrivers.push_back(driver);
+ driver->_groupOffset = driver->getGroupData();
+ driver->_groupMask = READ_LE_UINT32(driver->_groupOffset);
+
+ _sfExtractGroupMask();
+ _sfRethinkSoundDrivers();
+ driver->setMasterVolume(sfManager()._masterVol);
+
+ return true;
+}
+
+void SoundManager::_sfUnInstallDriver(SoundDriver *driver) {
+ sfManager()._installedDrivers.remove(driver);
+ delete driver;
+
+ _sfExtractGroupMask();
+ _sfRethinkSoundDrivers();
+}
+
+void SoundManager::_sfInstallPatchBank(SoundDriver *driver, const byte *bankData) {
+ driver->installPatch(bankData, _vm->_memoryManager.getSize(bankData));
+}
+
+/**
+ * Adds the specified sound in the playing sound list, inserting in order of priority
+ */
+void SoundManager::_sfDoAddToPlayList(Sound *sound) {
+ Common::StackLock slock2(sfManager()._serverSuspendedMutex);
+
+ Common::List<Sound *>::iterator i = sfManager()._playList.begin();
+ while ((i != sfManager()._playList.end()) && (sound->_priority > (*i)->_priority))
+ ++i;
+
+ sfManager()._playList.insert(i, sound);
+}
+
+/**
+ * Removes the specified sound from the play list
+ */
+bool SoundManager::_sfDoRemoveFromPlayList(Sound *sound) {
+ Common::StackLock slock(sfManager()._serverSuspendedMutex);
+
+ bool result = false;
+ for (Common::List<Sound *>::iterator i = sfManager()._playList.begin(); i != sfManager()._playList.end(); ++i) {
+ if (*i == sound) {
+ result = true;
+ sfManager()._playList.erase(i);
+ break;
+ }
+ }
+
+ return result;
+}
+
+void SoundManager::_sfDoUpdateVolume(Sound *sound) {
+ Common::StackLock slock(sfManager()._serverSuspendedMutex);
+
+ for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
+ VoiceTypeStruct *vs = sfManager()._voiceTypeStructPtrs[voiceIndex];
+ if (!vs)
+ continue;
+
+ for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
+ VoiceStructEntry &vse = vs->_entries[idx];
+ SoundDriver *driver = vse._driver;
+
+ if (vs->_voiceType == VOICETYPE_0) {
+ if (vse._type0._sound) {
+ int vol = sound->_volume * sound->_chVolume[vse._type0._channelNum] / 127;
+ driver->proc24(voiceIndex, vse._voiceNum, sound, 7, vol);
+ }
+ } else {
+ if (vse._type1._sound) {
+ int vol = sound->_volume * sound->_chVolume[vse._type1._channelNum] / 127;
+ driver->proc38(vse._voiceNum, 7, vol);
+ }
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Sound::Sound() {
+ _stoppedAsynchronously = false;
+ _soundResID = 0;
+ _group = 0;
+ _sndResPriority = 0;
+ _fixedPriority = -1;
+ _sndResLoop = 1;
+ _fixedLoop = -1;
+ _priority = 0;
+ _volume = 127;
+ _loop = 0;
+ _pausedCount = 0;
+ _mutedCount = 0;
+ _hold = 0xff;
+ _cueValue = -1;
+ _fadeDest = -1;
+ _fadeSteps = 0;
+ _fadeTicks = 0;
+ _fadeCounter = 0;
+ _stopAfterFadeFlag = false;
+ _timer = 0;
+ _newTimeIndex = 0;
+ _loopTimer = 0;
+ _trackInfo._numTracks = 0;
+ _primed = false;
+ _isEmpty = false;
+ _remoteReceiver = NULL;
+
+
+ memset(_chProgram, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chModulation, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chVolume, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chPan, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chDamper, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chPitchBlend, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chVoiceType, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chNumVoices, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chSubPriority, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_chFlags, 0, SOUND_ARR_SIZE * sizeof(int));
+ Common::set_to(_chWork, _chWork + SOUND_ARR_SIZE, false);
+ memset(_channelData, 0, SOUND_ARR_SIZE * sizeof(byte *));
+ memset(_trkChannel, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_trkState, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_trkLoopState, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_trkIndex, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_trkLoopIndex, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_trkRest, 0, SOUND_ARR_SIZE * sizeof(int));
+ memset(_trkLoopRest, 0, SOUND_ARR_SIZE * sizeof(int));
+}
+
+Sound::~Sound() {
+ stop();
+}
+
+void Sound::synchronize(Serializer &s) {
+ if (s.getVersion() < 6)
+ return;
+
+ assert(!_remoteReceiver);
+
+ s.syncAsSint16LE(_soundResID);
+ s.syncAsByte(_primed);
+ s.syncAsByte(_stoppedAsynchronously);
+ s.syncAsSint16LE(_group);
+ s.syncAsSint16LE(_sndResPriority);
+ s.syncAsSint16LE(_fixedPriority);
+ s.syncAsSint16LE(_sndResLoop);
+ s.syncAsSint16LE(_fixedLoop);
+ s.syncAsSint16LE(_priority);
+ s.syncAsSint16LE(_volume);
+ s.syncAsSint16LE(_loop);
+ s.syncAsSint16LE(_pausedCount);
+ s.syncAsSint16LE(_mutedCount);
+ s.syncAsSint16LE(_hold);
+ s.syncAsSint16LE(_cueValue);
+ s.syncAsSint16LE(_fadeDest);
+ s.syncAsSint16LE(_fadeSteps);
+ s.syncAsUint32LE(_fadeTicks);
+ s.syncAsUint32LE(_fadeCounter);
+ s.syncAsByte(_stopAfterFadeFlag);
+ s.syncAsUint32LE(_timer);
+ s.syncAsSint16LE(_loopTimer);
+}
+
+void Sound::play(int soundNum) {
+ prime(soundNum);
+ _soundManager->addToPlayList(this);
+}
+
+void Sound::stop() {
+ _globals->_soundManager.removeFromPlayList(this);
+ _unPrime();
+}
+
+void Sound::prime(int soundResID) {
+ if (_soundResID != -1) {
+ stop();
+ _prime(soundResID, false);
+ }
+}
+
+void Sound::unPrime() {
+ stop();
+}
+
+void Sound::_prime(int soundResID, bool dontQueue) {
+ if (_primed)
+ unPrime();
+
+ _soundResID = soundResID;
+ if (_soundResID != -1) {
+ // Sound number specified
+ _isEmpty = false;
+ _remoteReceiver = NULL;
+ byte *soundData = _resourceManager->getResource(RES_SOUND, soundResID, 0);
+ _soundManager->checkResVersion(soundData);
+ _group = _soundManager->determineGroup(soundData);
+ _sndResPriority = _soundManager->extractPriority(soundData);
+ _sndResLoop = _soundManager->extractLoop(soundData);
+ _soundManager->extractTrackInfo(&_trackInfo, soundData, _group);
+
+ for (int idx = 0; idx < _trackInfo._numTracks; ++idx) {
+ _channelData[idx] = _resourceManager->getResource(RES_SOUND, soundResID, _trackInfo._chunks[idx]);
+ }
+
+ DEALLOCATE(soundData);
+ } else {
+ // No sound specified
+ _isEmpty = true;
+ _group = 0;
+ _sndResPriority = 0;
+ _sndResLoop = 0;
+ _trackInfo._numTracks = 0;
+ _channelData[0] = ALLOCATE(200);
+ _remoteReceiver = ALLOCATE(200);
+ }
+
+ _soPrimeSound(dontQueue);
+ if (!dontQueue)
+ _soundManager->addToSoundList(this);
+
+ _primed = true;
+}
+
+void Sound::_unPrime() {
+ if (_primed) {
+ if (_isEmpty) {
+ DEALLOCATE(_channelData[0]);
+ DEALLOCATE(_remoteReceiver);
+ _remoteReceiver = NULL;
+ } else {
+ for (int idx = 0; idx < _trackInfo._numTracks; ++idx) {
+ DEALLOCATE(_channelData[idx]);
+ }
+ }
+
+ _trackInfo._numTracks = 0;
+ if (_soundManager)
+ _soundManager->removeFromSoundList(this);
+
+ _primed = false;
+ _stoppedAsynchronously = false;
+ }
+}
+
+void Sound::orientAfterDriverChange() {
+ if (!_isEmpty) {
+ int timeIndex = getTimeIndex();
+
+ for (int idx = 0; idx < _trackInfo._numTracks; ++idx)
+ DEALLOCATE(_channelData[idx]);
+
+ _trackInfo._numTracks = 0;
+ _primed = false;
+ _prime(_soundResID, true);
+
+ setTimeIndex(timeIndex);
+ }
+}
+
+void Sound::orientAfterRestore() {
+ if (!_isEmpty) {
+ int timeIndex = getTimeIndex();
+ _primed = false;
+ _prime(_soundResID, true);
+ setTimeIndex(timeIndex);
+ }
+}
+
+void Sound::go() {
+ if (!_primed)
+ error("Attempt to execute Sound::go() on an unprimed Sound");
+
+ _soundManager->addToPlayList(this);
+}
+
+void Sound::halt(void) {
+ _soundManager->removeFromPlayList(this);
+}
+
+int Sound::getSoundNum() const {
+ return _soundResID;
+}
+
+bool Sound::isPlaying() {
+ return _soundManager->isOnPlayList(this);
+}
+
+bool Sound::isPrimed() const {
+ return _primed;
+}
+
+bool Sound::isPaused() const {
+ return _pausedCount != 0;
+}
+
+bool Sound::isMuted() const {
+ return _mutedCount != 0;
+}
+
+void Sound::pause(bool flag) {
+ Common::StackLock slock(_globals->_soundManager._serverSuspendedMutex);
+
+ if (flag)
+ ++_pausedCount;
+ else if (_pausedCount > 0)
+ --_pausedCount;
+
+ _soundManager->rethinkVoiceTypes();
+}
+
+void Sound::mute(bool flag) {
+ Common::StackLock slock(_globals->_soundManager._serverSuspendedMutex);
+
+ if (flag)
+ ++_mutedCount;
+ else if (_mutedCount > 0)
+ --_mutedCount;
+
+ _soundManager->rethinkVoiceTypes();
+}
+
+void Sound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag) {
+ Common::StackLock slock(_globals->_soundManager._serverSuspendedMutex);
+
+ if (fadeDest > 127)
+ fadeDest = 127;
+ if (fadeTicks > 127)
+ fadeTicks = 127;
+ if (fadeSteps > 255)
+ fadeSteps = 255;
+
+ _fadeDest = fadeDest;
+ _fadeTicks = fadeTicks;
+ _fadeSteps = fadeSteps;
+ _fadeCounter = 0;
+ _stopAfterFadeFlag = stopAfterFadeFlag;
+}
+
+void Sound::setTimeIndex(uint32 timeIndex) {
+ if (_primed)
+ _newTimeIndex = timeIndex;
+}
+
+uint32 Sound::getTimeIndex() const {
+ return _timer;
+}
+
+int Sound::getCueValue() const {
+ return _cueValue;
+}
+
+void Sound::setCueValue(int cueValue) {
+ _cueValue = cueValue;
+}
+
+void Sound::setVol(int volume) {
+ if (volume > 127)
+ volume = 127;
+
+ if (_volume != volume) {
+ _volume = volume;
+ if (isPlaying())
+ _soundManager->updateSoundVol(this);
+ }
+}
+
+int Sound::getVol() const {
+ return _volume;
+}
+
+void Sound::setPri(int priority) {
+ if (priority > 127)
+ priority = 127;
+ _fixedPriority = priority;
+ _soundManager->updateSoundPri(this);
+}
+
+void Sound::setLoop(int flag) {
+ _fixedLoop = flag;
+ _soundManager->updateSoundLoop(this);
+}
+
+int Sound::getPri() const {
+ return _priority;
+}
+
+int Sound::getLoop() {
+ return _loop;
+}
+
+void Sound::holdAt(int amount) {
+ if (amount > 127)
+ amount = 127;
+ _hold = amount;
+}
+
+void Sound::release() {
+ _hold = -1;
+}
+
+void Sound::_soPrimeSound(bool dontQueue) {
+ if (!dontQueue) {
+ _priority = (_fixedPriority != -1) ? _fixedPriority : _sndResPriority;
+ _loop = !_fixedLoop ? _fixedLoop : _sndResLoop;
+ _pausedCount = 0;
+ _mutedCount = 0;
+ _hold = -1;
+ _cueValue = -1;
+ _fadeDest = -1;
+ _fadeSteps = 0;
+ _fadeTicks = 0;
+ _fadeCounter = 0;
+ _stopAfterFadeFlag = false;
+ }
+
+ _timer = 0;
+ _newTimeIndex = 0;
+ _loopTimer = 0;
+ _soPrimeChannelData();
+}
+
+void Sound::_soSetTimeIndex(uint timeIndex) {
+ Common::StackLock slock(_globals->_soundManager._serverSuspendedMutex);
+
+ if (timeIndex != _timer) {
+ _soundManager->_soTimeIndexFlag = true;
+ _timer = 0;
+ _loopTimer = 0;
+ _soPrimeChannelData();
+
+ while (timeIndex > 0) {
+ if (_soServiceTracks()) {
+ SoundManager::_sfDoRemoveFromPlayList(this);
+ _stoppedAsynchronously = true;
+ _soundManager->_needToRethink = true;
+ break;
+ }
+
+ --timeIndex;
+ }
+
+ _soundManager->_soTimeIndexFlag = false;
+ }
+}
+
+bool Sound::_soServiceTracks() {
+ if (_isEmpty) {
+ _soRemoteReceive();
+ return false;
+ }
+
+ bool flag = true;
+ for (int trackCtr = 0; trackCtr < _trackInfo._numTracks; ++trackCtr) {
+ int mode = *_channelData[trackCtr];
+
+ if (mode == 0) {
+ _soServiceTrackType0(trackCtr, _channelData[trackCtr]);
+ } else if (mode == 1) {
+ _soServiceTrackType1(trackCtr, _channelData[trackCtr]);
+ } else {
+ error("Unknown sound mode encountered");
+ }
+
+ if (_trkState[trackCtr])
+ flag = false;
+ }
+
+ ++_timer;
+ if (!flag)
+ return false;
+ else if ((_loop > 0) && (--_loop == 0))
+ return true;
+ else {
+ for (int trackCtr = 0; trackCtr < _trackInfo._numTracks; ++trackCtr) {
+ _trkState[trackCtr] = _trkLoopState[trackCtr];
+ _trkRest[trackCtr] = _trkLoopRest[trackCtr];
+ _trkIndex[trackCtr] = _trkLoopIndex[trackCtr];
+ }
+
+ _timer = _loopTimer;
+ return false;
+ }
+}
+
+void Sound::_soPrimeChannelData() {
+ if (_isEmpty) {
+ for (int idx = 0; idx < 16; ++idx) {
+ _chProgram[idx] = 0;
+ _chModulation[idx] = 0;
+ _chVolume[idx] = 127;
+ _chPan[idx] = 64;
+ _chDamper[idx] = 0;
+ _chVoiceType[idx] = VOICETYPE_0;
+ _chNumVoices[idx] = 0;
+ _chSubPriority[idx] = 0;
+ _chPitchBlend[idx] = 0x2000;
+ _chFlags[idx] = 1;
+ }
+
+ _trkChannel[0] = 0;
+ _trkState[0] = 1;
+ _trkLoopState[0] = 1;
+ _trkIndex[0] = 0;
+ _trkLoopIndex[0] = 0;
+ } else {
+ for (int idx = 0; idx < SOUND_ARR_SIZE; ++idx)
+ _chFlags[idx] = 0x8000;
+
+ for (int idx = 0; idx < _trackInfo._numTracks; ++idx) {
+ byte *d = _channelData[idx];
+ int mode = *d;
+ int channelNum = (int8)*(d + 1);
+
+ _trkChannel[idx] = channelNum;
+ assert((channelNum >= -1) && (channelNum < 16));
+
+ if (channelNum >= 0) {
+ _chProgram[channelNum] = *(d + 10);
+ _chModulation[channelNum] = 0;
+ _chVolume[channelNum] = *(d + 11);
+ _chPan[channelNum] = *(d + 12);
+ _chDamper[channelNum] = 0;
+ _chVoiceType[channelNum] = _trackInfo._voiceTypes[idx];
+ _chNumVoices[channelNum] = *(d + 6);
+ _chSubPriority[channelNum] = *(d + 7);
+ _chPitchBlend[channelNum] = 0x2000;
+ _chFlags[channelNum] = READ_LE_UINT16(d + 8);
+ }
+
+ if (mode == 0) {
+ _trkState[idx] = 1;
+ _trkLoopState[idx] = 1;
+ _trkIndex[idx] = 14;
+ _trkLoopIndex[idx] = 14;
+ _trkRest[idx] = 0;
+ _trkLoopRest[idx] = 0;
+ } else if (mode == 1) {
+ _trkState[idx] = 1;
+ _trkLoopState[idx] = 1;
+ _trkIndex[idx] = 0;
+ _trkLoopIndex[idx] = 0;
+ _trkRest[idx] = 0;
+ _trkLoopRest[idx] = 0;
+ } else {
+ error("Unknown sound mode encountered");
+ }
+ }
+ }
+}
+
+void Sound::_soRemoteReceive() {
+ error("_soRemoteReceive not implemented");
+}
+
+void Sound::_soServiceTrackType0(int trackIndex, const byte *channelData) {
+ if (_trkRest[trackIndex]) {
+ --_trkRest[trackIndex];
+ return;
+ }
+ if (!_trkState[trackIndex])
+ return;
+
+ int channelNum = _trkChannel[trackIndex];
+ assert((channelNum >= -1) && (channelNum < SOUND_ARR_SIZE));
+ int chFlags = (channelNum == -1) ? 0 : _chFlags[channelNum];
+ int voiceNum = -1;
+ SoundDriver *driver = NULL;
+
+ VoiceTypeStruct *vtStruct;
+ VoiceType voiceType = VOICETYPE_0, chVoiceType = VOICETYPE_0;
+
+ if ((channelNum == -1) || _soundManager->_soTimeIndexFlag) {
+ vtStruct = NULL;
+ voiceType = VOICETYPE_0;
+ } else {
+ chVoiceType = (VoiceType)_chVoiceType[channelNum];
+ vtStruct = _soundManager->_voiceTypeStructPtrs[(int)chVoiceType];
+
+ if (vtStruct) {
+ voiceType = vtStruct->_voiceType;
+ if (voiceType == VOICETYPE_0) {
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ if (!vtStruct->_entries[idx]._type0._sound &&
+ (vtStruct->_entries[idx]._type0._channelNum != channelNum)) {
+ voiceNum = vtStruct->_entries[idx]._voiceNum;
+ driver = vtStruct->_entries[idx]._driver;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ const byte *pData = channelData + _trkIndex[trackIndex];
+
+ for (;;) {
+ byte v = *pData++;
+ if (!(v & 0x80)) {
+ // Area #1
+ if (!_soundManager->_soTimeIndexFlag) {
+ // Only do processing if fast forwarding to a given time index
+ if (channelNum != -1) {
+ if (voiceType == VOICETYPE_1) {
+ _soUpdateDamper(vtStruct, channelNum, chVoiceType, v);
+ } else if (voiceNum != -1) {
+ assert(driver);
+ driver->proc18(voiceNum, chVoiceType);
+ }
+ }
+ }
+ } else if (!(v & 0x40)) {
+ // Area #2
+ if (!_soundManager->_soTimeIndexFlag) {
+ // Only do processing if fast forwarding to a given time index
+ byte b = *pData++;
+ v <<= 1;
+ if (b & 0x80)
+ v |= 1;
+
+ b &= 0x7f;
+
+ if (channelNum != -1) {
+ if (voiceType != VOICETYPE_0) {
+ if (chFlags & 0x10)
+ _soProc42(vtStruct, channelNum, chVoiceType, v);
+ else
+ _soProc32(vtStruct, channelNum, chVoiceType, v, b);
+ } else if (voiceNum != -1) {
+ assert(driver);
+ driver->proc20(voiceNum, chVoiceType);
+ }
+ }
+ } else {
+ ++pData;
+ }
+ } else if (!(v & 0x20)) {
+ // Area #3
+ v &= 0x1f;
+
+ // Gather up an extended number
+ int trkRest = v;
+ while ((*pData & 0xE0) == 0xC0) {
+ byte b = *pData++;
+ trkRest = (trkRest << 5) | (b & 0x1f);
+ }
+
+ _trkRest[trackIndex] = trkRest - 1;
+ _trkIndex[trackIndex] = pData - channelData;
+ return;
+ } else if (!(v & 0x10)) {
+ // Area #4
+ v = (v & 0xf) << 1;
+
+ byte b = *pData++;
+ if (b & 0x80)
+ v |= 1;
+ b &= 0x7f;
+
+ assert(v < 4);
+ int cmdList[32] = { 1, 7, 10, 64 };
+ int cmdVal = cmdList[v];
+
+ if (channelNum == -1) {
+ if (_soDoUpdateTracks(cmdVal, b))
+ return;
+ } else {
+ _soDoTrackCommand(_trkChannel[trackIndex], cmdVal, b);
+
+ if (!_soundManager->_soTimeIndexFlag) {
+ if (cmdVal == 7)
+ b = static_cast<byte>(_volume * (int)b / 127);
+
+ if (voiceType != VOICETYPE_0) {
+ _soProc38(vtStruct, channelNum, chVoiceType, cmdVal, b);
+ } else if (voiceNum != -1) {
+ assert(driver);
+ driver->proc24(voiceNum, chVoiceType, this, cmdVal, b);
+ }
+ }
+ }
+ } else if (!(v & 0x8)) {
+ // Area #5
+ if (!_soundManager->_soTimeIndexFlag) {
+ // Only do processing if fast forwarding to a given time index
+ int cx = READ_LE_UINT16(pData);
+ pData += 2;
+
+ if (channelNum != -1) {
+ assert(driver);
+ driver->proc22(voiceNum, chVoiceType, cx);
+ }
+ } else {
+ pData += 2;
+ }
+ } else if (!(v & 0x4)) {
+ // Area #6
+ int cmd = *pData++;
+ int value = *pData++;
+
+ if (channelNum != -1) {
+ _soDoTrackCommand(_trkChannel[trackIndex], cmd, value);
+
+ if (!_soundManager->_soTimeIndexFlag) {
+ if (voiceType != VOICETYPE_0) {
+ _soProc38(vtStruct, channelNum, chVoiceType, cmd, value);
+ } else if (voiceNum != -1) {
+ assert(driver);
+ driver->proc24(voiceNum, chVoiceType, this, cmd, value);
+ }
+ }
+ } else if (_soDoUpdateTracks(cmd, value)) {
+ return;
+ }
+ } else if (!(v & 0x2)) {
+ // Area #7
+ if (!_soundManager->_soTimeIndexFlag) {
+ int pitchBlend = READ_BE_UINT16(pData);
+ pData += 2;
+
+ if (channelNum != -1) {
+ int channel = _trkChannel[trackIndex];
+ _chPitchBlend[channel] = pitchBlend;
+
+ if (voiceType != VOICETYPE_0) {
+ _soProc40(vtStruct, channelNum, pitchBlend);
+ } else if (voiceNum != -1) {
+ assert(driver);
+ driver->setPitchBlend(channel, pitchBlend);
+ }
+ }
+ } else {
+ pData += 2;
+ }
+ } else if (!(v & 0x1)) {
+ // Area #8
+ int program = *pData++;
+
+ if (channelNum != -1) {
+ int channel = _trkChannel[trackIndex];
+ _chProgram[channel] = program;
+
+ if (!_soundManager->_soTimeIndexFlag) {
+ if ((voiceType == VOICETYPE_0) && (voiceNum != -1)) {
+ assert(driver);
+ driver->setProgram(voiceNum, program);
+ }
+ }
+ } else {
+ _soSetTrackPos(trackIndex, pData - channelData, program);
+ }
+
+ } else {
+ // Area #9
+ byte b = *pData++;
+
+ if (b & 0x80) {
+ _trkState[trackIndex] = 0;
+ _trkIndex[trackIndex] = pData - channelData;
+ return;
+ }
+
+ if (!_soundManager->_soTimeIndexFlag) {
+ if ((channelNum != -1) && (voiceType == VOICETYPE_0) && (voiceNum != -1)) {
+ assert(driver);
+ driver->setVolume1(voiceNum, chVoiceType, 0, b);
+ }
+
+ }
+ }
+ }
+}
+
+void Sound::_soUpdateDamper(VoiceTypeStruct *voiceType, int channelNum, VoiceType mode, int v0) {
+ bool hasDamper = _chDamper[channelNum] != 0;
+
+ for (uint idx = 0; idx < voiceType->_entries.size(); ++idx) {
+ VoiceStructEntryType1 &vte = voiceType->_entries[idx]._type1;
+
+ if ((vte._field4 == v0) && (vte._channelNum == channelNum) && (vte._sound == this)) {
+ if (hasDamper)
+ vte._field5 = 1;
+ else {
+ SoundDriver *driver = voiceType->_entries[idx]._driver;
+ assert(driver);
+
+ vte._field4 = -1;
+ vte._field5 = 0;
+ driver->updateVoice(voiceType->_entries[idx]._voiceNum);
+ }
+ return;
+ }
+ }
+}
+
+void Sound::_soProc32(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0, int v1) {
+ int entryIndex = _soFindSound(vtStruct, channelNum);
+ if (entryIndex != -1) {
+ SoundDriver *driver = vtStruct->_entries[entryIndex]._driver;
+ assert(driver);
+
+ vtStruct->_entries[entryIndex]._type1._field6 = 0;
+ vtStruct->_entries[entryIndex]._type1._field4 = v0;
+ vtStruct->_entries[entryIndex]._type1._field5 = 0;
+
+ driver->proc32(vtStruct->_entries[entryIndex]._voiceNum, _chProgram[channelNum], v0, v1);
+ }
+}
+
+void Sound::_soProc42(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0) {
+ for (int trackCtr = 0; trackCtr < _trackInfo._numTracks; ++trackCtr) {
+ const byte *instrument = _channelData[trackCtr];
+ if ((*(instrument + 13) == v0) && (*instrument == 1)) {
+ int entryIndex = _soFindSound(vtStruct, channelNum);
+
+ if (entryIndex != -1) {
+ SoundDriver *driver = vtStruct->_entries[entryIndex]._driver;
+ assert(driver);
+
+ vtStruct->_entries[entryIndex]._type1._field6 = 0;
+ vtStruct->_entries[entryIndex]._type1._field4 = v0;
+ vtStruct->_entries[entryIndex]._type1._field5 = 0;
+
+ driver->proc32(vtStruct->_entries[entryIndex]._voiceNum, -1, v0, 0x7F);
+ driver->proc42(vtStruct->_entries[entryIndex]._voiceNum, voiceType, 0);
+ }
+ break;
+ }
+ }
+}
+
+void Sound::_soProc38(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int cmd, int value) {
+ if (cmd == 64) {
+ if (value == 0) {
+ for (uint entryIndex = 0; entryIndex < vtStruct->_entries.size(); ++entryIndex) {
+ VoiceStructEntryType1 &vte = vtStruct->_entries[entryIndex]._type1;
+
+ if ((vte._sound == this) && (vte._channelNum == channelNum) && (vte._field5 != 0)) {
+ SoundDriver *driver = vtStruct->_entries[entryIndex]._driver;
+ assert(driver);
+
+ vte._field4 = -1;
+ vte._field5 = 0;
+ driver->updateVoice(vtStruct->_entries[entryIndex]._voiceNum);
+ }
+ }
+ }
+ } else if (cmd == 75) {
+ _soundManager->_needToRethink = true;
+ } else {
+ for (uint entryIndex = 0; entryIndex < vtStruct->_entries.size(); ++entryIndex) {
+ VoiceStructEntry &vte = vtStruct->_entries[entryIndex];
+
+ if ((vte._type1._sound == this) && (vte._type1._channelNum == channelNum)) {
+ SoundDriver *driver = vte._driver;
+ assert(driver);
+
+ driver->proc38(vte._voiceNum, cmd, value);
+ }
+ }
+ }
+}
+
+void Sound::_soProc40(VoiceTypeStruct *vtStruct, int channelNum, int pitchBlend) {
+ for (uint entryIndex = 0; entryIndex < vtStruct->_entries.size(); ++entryIndex) {
+ VoiceStructEntryType1 &vte = vtStruct->_entries[entryIndex]._type1;
+
+ if ((vte._sound == this) && (vte._channelNum == channelNum)) {
+ SoundDriver *driver = vtStruct->_entries[entryIndex]._driver;
+ assert(driver);
+
+ driver->setPitch(vtStruct->_entries[entryIndex]._voiceNum, pitchBlend);
+ }
+ }
+}
+
+void Sound::_soDoTrackCommand(int channelNum, int command, int value) {
+ switch (command) {
+ case 1:
+ _chModulation[channelNum] = value;
+ break;
+ case 7:
+ _chVolume[channelNum] = value;
+ break;
+ case 10:
+ _chPan[channelNum] = value;
+ break;
+ case 64:
+ _chDamper[channelNum] = value;
+ break;
+ case 75:
+ _chNumVoices[channelNum] = value;
+ break;
+ }
+}
+
+bool Sound::_soDoUpdateTracks(int command, int value) {
+ if ((command == 76) || (_hold != value))
+ return false;
+
+ for (int trackIndex = 0; trackIndex < _trackInfo._numTracks; ++trackIndex) {
+ _trkState[trackIndex] = _trkLoopState[trackIndex];
+ _trkRest[trackIndex] = _trkLoopRest[trackIndex];
+ _trkIndex[trackIndex] = _trkLoopIndex[trackIndex];
+ }
+
+ _timer = _loopTimer;
+ return true;
+}
+
+void Sound::_soSetTrackPos(int trackIndex, int trackPos, int cueValue) {
+ _trkIndex[trackIndex] = trackPos;
+ if (cueValue == 127) {
+ if (!_soundManager->_soTimeIndexFlag)
+ _cueValue = cueValue;
+ } else {
+ for (int idx = 0; idx < _trackInfo._numTracks; ++idx) {
+ _trkLoopState[idx] = _trkState[idx];
+ _trkLoopRest[idx] = _trkRest[idx];
+ _trkLoopIndex[idx] = _trkIndex[idx];
+ }
+
+ _loopTimer = _timer;
+ }
+}
+
+void Sound::_soServiceTrackType1(int trackIndex, const byte *channelData) {
+ if (_soundManager->_soTimeIndexFlag || !_trkState[trackIndex])
+ return;
+
+ int channel = _trkChannel[trackIndex];
+ if (channel == -1)
+ _trkState[trackIndex] = 0;
+ else {
+ int voiceType = _chVoiceType[channel];
+ VoiceTypeStruct *vtStruct = _soundManager->_voiceTypeStructPtrs[voiceType];
+
+ if (!vtStruct)
+ _trkState[trackIndex] = 0;
+ else {
+ if (vtStruct->_voiceType != VOICETYPE_0) {
+ if (_trkState[trackIndex] == 1) {
+ int entryIndex = _soFindSound(vtStruct, *(channelData + 1));
+ if (entryIndex != -1) {
+ SoundDriver *driver = vtStruct->_entries[entryIndex]._driver;
+ assert(driver);
+
+ vtStruct->_entries[entryIndex]._type1._field6 = 0;
+ vtStruct->_entries[entryIndex]._type1._field4 = *(channelData + 1);
+ vtStruct->_entries[entryIndex]._type1._field5 = 0;
+
+ driver->proc32(vtStruct->_entries[entryIndex]._voiceNum, -1, *(channelData + 1), 0x7f);
+ }
+ } else {
+
+ }
+ }
+ }
+ }
+}
+
+int Sound::_soFindSound(VoiceTypeStruct *vtStruct, int channelNum) {
+ int entryIndex = -1, entry2Index = -1;
+ int v6 = 0, v8 = 0;
+
+ for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
+ VoiceStructEntryType1 &vte = vtStruct->_entries[idx]._type1;
+ if ((vte._channelNum == channelNum) && (vte._sound == this)) {
+ int v = vte._field6;
+ if (vte._field4 != -1) {
+ if (v8 <= v) {
+ v8 = v;
+ entry2Index = idx;
+ }
+ } else {
+ if (v6 <= v) {
+ v6 = v;
+ entryIndex = idx;
+ }
+ }
+ }
+ }
+
+ if (entryIndex != -1)
+ return entryIndex;
+ else if ((entryIndex == -1) && (entry2Index == -1))
+ return -1;
+ else {
+ SoundDriver *driver = vtStruct->_entries[entry2Index]._driver;
+ assert(driver);
+ driver->updateVoice(vtStruct->_entries[entry2Index]._voiceNum);
+
+ return entry2Index;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+ASound::ASound(): EventHandler() {
+ _action = NULL;
+ _cueValue = -1;
+ if (_globals)
+ _globals->_sounds.push_back(this);
+}
+
+ASound::~ASound() {
+ if (_globals)
+ _globals->_sounds.remove(this);
+}
+
+void ASound::synchronize(Serializer &s) {
+ EventHandler::synchronize(s);
+
+ SYNC_POINTER(_action);
+ s.syncAsByte(_cueValue);
+
+}
+
+void ASound::dispatch() {
+ EventHandler::dispatch();
+
+ int cueValue = _sound.getCueValue();
+ if (cueValue != -1) {
+ _cueValue = cueValue;
+ _sound.setCueValue(-1);
+
+ if (_action)
+ _action->signal();
+ }
+
+ if (_cueValue != -1) {
+ if (!_sound.isPrimed()) {
+ _cueValue = -1;
+ if (_action) {
+ _action->signal();
+ _action = NULL;
+ }
+ }
+ }
+}
+
+void ASound::play(int soundNum, Action *action, int volume) {
+ _action = action;
+ _cueValue = 0;
+
+ setVol(volume);
+ _sound.play(soundNum);
+}
+
+void ASound::stop() {
+ _sound.stop();
+ _action = NULL;
+}
+
+void ASound::prime(int soundResID, Action *action) {
+ _action = action;
+ _cueValue = 0;
+ _sound.prime(soundResID);
+}
+
+void ASound::unPrime() {
+ _sound.unPrime();
+ _action = NULL;
+}
+
+void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, Action *action) {
+ if (action)
+ _action = action;
+
+ _sound.fade(fadeDest, fadeSteps, fadeTicks, stopAfterFadeFlag);
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+SoundDriver::SoundDriver() {
+ _driverResID = 0;
+ _minVersion = _maxVersion = 0;
+ _groupMask = 0;
+}
+
+/*--------------------------------------------------------------------------*/
+
+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 v44134[64] = {
+ 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 47, 48, 49, 50, 50, 51, 52, 52, 53, 54, 54, 55,
+ 56, 56, 57, 57, 58, 58, 59, 59, 59, 60, 60, 60, 61, 61,
+ 61, 62, 62, 62, 62, 63, 63, 63
+};
+
+const int v440D4[48] = {
+ 343, 348, 353, 358, 363, 369, 374, 379, 385, 391, 396,
+ 402, 408, 414, 420, 426, 432, 438, 445, 451, 458, 465,
+ 471, 478, 485, 492, 499, 507, 514, 521, 529, 537, 544,
+ 552, 560, 569, 577, 585, 594, 602, 611, 620, 629, 638,
+ 647, 657, 666, 676
+};
+
+AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
+ _minVersion = 0x102;
+ _maxVersion = 0x10A;
+ _masterVolume = 0;
+
+ _groupData.groupMask = 9;
+ _groupData.v1 = 0x46;
+ _groupData.v2 = 0;
+ _groupData.pData = &adlib_group_data[0];
+
+ _mixer = _vm->_mixer;
+ _sampleRate = _mixer->getOutputRate();
+ _opl = makeAdLibOPL(_sampleRate);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+ Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false);
+ memset(_channelVolume, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v4405E, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44067, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44070, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44079, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44082, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ _v44082[ADLIB_CHANNEL_COUNT] = 0x90;
+ Common::set_to(_pitchBlend, _pitchBlend + ADLIB_CHANNEL_COUNT, 0x2000);
+ memset(_v4409E, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ _patchData = NULL;
+}
+
+AdlibSoundDriver::~AdlibSoundDriver() {
+ DEALLOCATE(_patchData);
+ _mixer->stopHandle(_soundHandle);
+ OPLDestroy(_opl);
+}
+
+bool AdlibSoundDriver::open() {
+ write(1, 0x20);
+ if (!reset())
+ return false;
+
+ write(8, 0);
+ for (int idx = 0x20; idx < 0xF6; ++idx)
+ write(idx, 0);
+
+ write(0xBD, 0);
+ return true;
+}
+
+void AdlibSoundDriver::close() {
+ for (int idx = 0xB0; idx < 0xB8; ++idx)
+ write(idx, _portContents[idx] & 0xDF);
+ for (int idx = 0x40; idx < 0x55; ++idx)
+ write(idx, 0x3F);
+ reset();
+}
+
+bool AdlibSoundDriver::reset() {
+ write(1, 0x20);
+ write(1, 0x20);
+
+ return true;
+}
+
+const GroupData *AdlibSoundDriver::getGroupData() {
+ return &_groupData;
+}
+
+void AdlibSoundDriver::installPatch(const byte *data, int size) {
+ byte *patchData = ALLOCATE(size);
+ Common::copy(data, data + size, patchData);
+ _patchData = patchData;
+}
+
+int AdlibSoundDriver::setMasterVolume(int volume) {
+ int oldVolume = _masterVolume;
+ _masterVolume = volume;
+
+ for (int channelNum = 0; channelNum < ADLIB_CHANNEL_COUNT; ++channelNum)
+ updateChannelVolume(channelNum);
+
+ return oldVolume;
+}
+
+void AdlibSoundDriver::proc32(int channel, int program, int v0, int v1) {
+ if (program == -1)
+ return;
+
+ int offset = READ_LE_UINT16(_patchData + program * 2);
+ if (offset) {
+ const byte *dataP = _patchData + offset;
+ int id;
+
+ for (offset = 2, id = 0; id != READ_LE_UINT16(dataP); offset += 30, ++id) {
+ if ((dataP[offset] <= v0) && (dataP[offset + 1] >= v0)) {
+ if (dataP[offset + 2] != 0xff)
+ v0 = dataP[offset + 2];
+
+ _v4409E[channel] = dataP + offset - _patchData;
+
+ // Set sustain/release
+ int portNum = v440C2[v440B0[channel]] + 0x80;
+ write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
+
+ portNum = v440C2[v440B9[channel]] + 0x80;
+ write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
+
+ if (_channelVoiced[channel])
+ clearVoice(channel);
+
+ _v44067[channel] = v0;
+ _v4405E[channel] = v1;
+
+ updateChannel(channel);
+ setFrequency(channel);
+ updateChannelVolume(channel);
+ setVoice(channel);
+ break;
+ }
+ }
+ }
+}
+
+void AdlibSoundDriver::updateVoice(int channel) {
+ if (_channelVoiced[channel])
+ clearVoice(channel);
+}
+
+void AdlibSoundDriver::proc38(int channel, int cmd, int value) {
+ if (cmd == 7) {
+ // Set channel volume
+ _channelVolume[channel] = value;
+ updateChannelVolume(channel);
+ }
+}
+
+void AdlibSoundDriver::setPitch(int channel, int pitchBlend) {
+ _pitchBlend[channel] = pitchBlend;
+ setFrequency(channel);
+}
+
+void AdlibSoundDriver::write(byte reg, byte value) {
+ _portContents[reg] = value;
+ _queue.push(RegisterValue(reg, value));
+}
+
+void AdlibSoundDriver::flush() {
+ Common::StackLock slock(SoundManager::sfManager()._serverDisabledMutex);
+
+ while (!_queue.empty()) {
+ RegisterValue v = _queue.pop();
+ OPLWriteReg(_opl, v._regNum, v._value);
+ }
+}
+
+void AdlibSoundDriver::updateChannelVolume(int channelNum) {
+ int volume = (_masterVolume * _channelVolume[channelNum] / 127 * _v4405E[channelNum] / 127) / 2;
+ int level2 = 63 - v44134[volume * _v44079[channelNum] / 63];
+ int level1 = !_v44082[channelNum] ? 63 - _v44070[channelNum] :
+ 63 - v44134[volume * _v44070[channelNum] / 63];
+
+ int portNum = v440C2[v440B0[channelNum]] + 0x40;
+ write(portNum, (_portContents[portNum] & 0x80) | level1);
+
+ portNum = v440C2[v440B9[channelNum]] + 0x40;
+ write(portNum, (_portContents[portNum] & 0x80) | level2);
+}
+
+void AdlibSoundDriver::setVoice(int channel) {
+ int portNum = 0xB0 + channel;
+ write(portNum, _portContents[portNum] | 0x20);
+ _channelVoiced[channel] = true;
+}
+
+void AdlibSoundDriver::clearVoice(int channel) {
+ write(0xB0 + channel, _portContents[0xB0 + channel] & ~0x20);
+ _channelVoiced[channel] = false;
+}
+
+void AdlibSoundDriver::updateChannel(int channel) {
+ const byte *dataP = _patchData + _v4409E[channel];
+ int portOffset = v440C2[v440B0[channel]];
+
+ int portNum = portOffset + 0x20;
+ int portValue = 0;
+ if (*(dataP + 4))
+ portValue |= 0x80;
+ if (*(dataP + 5))
+ portValue |= 0x40;
+ if (*(dataP + 8))
+ portValue |= 0x20;
+ if (*(dataP + 6))
+ portValue |= 0x10;
+ portValue |= *(dataP + 7);
+ write(portNum, portValue);
+
+ portValue = (_portContents[0x40 + portOffset] & 0x3F) | (*(dataP + 9) << 6);
+ write(0x40 + portOffset, portValue);
+
+ _v44070[channel] = 63 - *(dataP + 10);
+ write(0x60 + portOffset, *(dataP + 12) | (*(dataP + 11) << 4));
+ write(0x80 + portOffset, *(dataP + 14) | (*(dataP + 13) << 4));
+ write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 15));
+
+ portOffset = v440C2[v440B9[channel]];
+ portNum = portOffset + 0x20;
+ portValue = 0;
+ if (*(dataP + 17))
+ portValue |= 0x80;
+ if (*(dataP + 18))
+ portValue |= 0x40;
+ if (*(dataP + 21))
+ portValue |= 0x20;
+ if (*(dataP + 19))
+ portValue |= 0x10;
+ portValue |= *(dataP + 20);
+ write(portNum, portValue);
+
+ write(0x40 + portOffset, (_portContents[0x40 + portOffset] & 0x3f) | (*(dataP + 22) << 6));
+ _v44079[channel] = 0x3F - *(dataP + 23);
+ write(0x60 + portOffset, *(dataP + 25) | (*(dataP + 24) << 4));
+ write(0x80 + portOffset, *(dataP + 27) | (*(dataP + 26) << 4));
+ write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 28));
+
+ write(0xC0 + channel, (_portContents[0xC0 + channel] & 0xF0)
+ | (*(dataP + 16) << 1) | *(dataP + 3));
+
+ _v44082[channel] = *(dataP + 3);
+}
+
+void AdlibSoundDriver::setFrequency(int channel) {
+ int offset, ch;
+
+ int v = _pitchBlend[channel];
+ if (v == 0x2000) {
+ offset = 0;
+ ch = _v44067[channel];
+ } else if (v > 0x2000) {
+ ch = _v44067[channel];
+ v -= 0x2000;
+ if (v == 0x1fff)
+ v = 0x2000;
+
+ offset = (v / 170) & 3;
+ ch += (v / 170) >> 2;
+
+ if (ch >= 128)
+ ch = 127;
+ } else {
+ ch = _v44067[channel];
+ int tempVal = (0x2000 - v) / 170;
+ int tempVal2 = 4 - (tempVal & 3);
+
+ if (tempVal2 == 4)
+ offset = 0;
+ else {
+ offset = tempVal2;
+ --ch;
+ }
+
+ ch -= tempVal >> 2;
+ if (ch < 0)
+ ch = 0;
+ }
+
+ int var2 = ch / 12;
+ if (var2)
+ --var2;
+
+ int dataWord = v440D4[((ch % 12) << 2) + offset];
+ write(0xA0 + channel, dataWord & 0xff);
+ write(0xB0 + channel, (_portContents[0xB0 + channel] & 0xE0) |
+ ((dataWord >> 8) & 3) | (var2 << 2));
+}
+
+int AdlibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
+ update(buffer, numSamples);
+ return numSamples;
+}
+
+void AdlibSoundDriver::update(int16 *buf, int len) {
+ static int samplesLeft = 0;
+ while (len != 0) {
+ int count = samplesLeft;
+ if (count > len) {
+ count = len;
+ }
+ samplesLeft -= count;
+ len -= count;
+ YM3812UpdateOne(_opl, buf, count);
+ if (samplesLeft == 0) {
+ flush();
+ samplesLeft = _sampleRate / 50;
+ }
+ buf += count;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+const byte adlibFx_group_data[] = { 3, 1, 1, 0, 0xff };
+
+
+AdlibFxSoundDriver::AdlibFxSoundDriver(): SoundDriver() {
+ _minVersion = 0x102;
+ _maxVersion = 0x10A;
+ _masterVolume = 0;
+
+ _groupData.groupMask = 9;
+ _groupData.v1 = 0x3E;
+ _groupData.v2 = 0;
+ _groupData.pData = &adlib_group_data[0];
+
+ _mixer = _vm->_mixer;
+ _sampleRate = _mixer->getOutputRate();
+ _opl = makeAdLibOPL(_sampleRate);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+/*
+ Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false);
+ memset(_channelVolume, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v4405E, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44067, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44070, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44079, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ memset(_v44082, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ _v44082[ADLIB_CHANNEL_COUNT] = 0x90;
+ Common::set_to(_pitchBlend, _pitchBlend + ADLIB_CHANNEL_COUNT, 0x2000);
+ memset(_v4409E, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
+ _patchData = NULL;
+*/
+}
+
+AdlibFxSoundDriver::~AdlibFxSoundDriver() {
+ _mixer->stopHandle(_soundHandle);
+ OPLDestroy(_opl);
+}
+
+bool AdlibFxSoundDriver::open() {
+
+
+ write(1, 0x20);
+ if (!reset())
+ return false;
+
+ write(8, 0);
+ for (int idx = 0x20; idx < 0xF6; ++idx)
+ write(idx, 0);
+
+ write(0xBD, 0);
+ return true;
+}
+
+void AdlibFxSoundDriver::close() {
+ for (int idx = 0xB0; idx < 0xB8; ++idx)
+ write(idx, _portContents[idx] & 0xDF);
+ for (int idx = 0x40; idx < 0x55; ++idx)
+ write(idx, 0x3F);
+ reset();
+}
+
+bool AdlibFxSoundDriver::reset() {
+ write(1, 0x20);
+ write(1, 0x20);
+
+ return true;
+}
+
+const GroupData *AdlibFxSoundDriver::getGroupData() {
+ return &_groupData;
+}
+
+int AdlibFxSoundDriver::setMasterVolume(int volume) {
+ int oldVolume = _masterVolume;
+ _masterVolume = volume;
+
+ for (int channelNum = 0; channelNum < ADLIB_CHANNEL_COUNT; ++channelNum)
+ updateChannelVolume(channelNum);
+
+ return oldVolume;
+}
+
+void AdlibFxSoundDriver::proc32(int channel, int program, int v0, int v1) {
+ if (program == -1)
+ return;
+/*
+ int offset = READ_LE_UINT16(_patchData + program * 2);
+ if (offset) {
+ const byte *dataP = _patchData + offset;
+ int id;
+
+ for (offset = 2, id = 0; id != READ_LE_UINT16(dataP); offset += 30, ++id) {
+ if ((dataP[offset] <= v0) && (dataP[offset + 1] >= v0)) {
+ if (dataP[offset + 2] != 0xff)
+ v0 = dataP[offset + 2];
+
+ _v4409E[channel] = dataP + offset - _patchData;
+
+ // Set sustain/release
+ int portNum = v440C2[v440B0[channel]] + 0x80;
+ write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
+
+ portNum = v440C2[v440B9[channel]] + 0x80;
+ write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
+
+ if (_channelVoiced[channel])
+ clearVoice(channel);
+
+ _v44067[channel] = v0;
+ _v4405E[channel] = v1;
+
+ updateChannel(channel);
+ setFrequency(channel);
+ updateChannelVolume(channel);
+ setVoice(channel);
+ break;
+ }
+ }
+ }
+ */
+}
+
+void AdlibFxSoundDriver::updateVoice(int channel) {
+ if (_channelVoiced[channel])
+ clearVoice(channel);
+}
+
+void AdlibFxSoundDriver::proc38(int channel, int cmd, int value) {
+ if (cmd == 7) {
+ // Set channel volume
+ _channelVolume[channel] = value;
+ updateChannelVolume(channel);
+ }
+}
+
+void AdlibFxSoundDriver::setPitch(int channel, int pitchBlend) {
+ _pitchBlend[channel] = pitchBlend;
+ setFrequency(channel);
+}
+
+void AdlibFxSoundDriver::write(byte reg, byte value) {
+ _portContents[reg] = value;
+ _queue.push(RegisterValue(reg, value));
+}
+
+void AdlibFxSoundDriver::flush() {
+ Common::StackLock slock(SoundManager::sfManager()._serverDisabledMutex);
+
+ while (!_queue.empty()) {
+ RegisterValue v = _queue.pop();
+ OPLWriteReg(_opl, v._regNum, v._value);
+ }
+}
+
+void AdlibFxSoundDriver::updateChannelVolume(int channelNum) {
+ int volume = (_masterVolume * _channelVolume[channelNum] / 127 * _v4405E[channelNum] / 127) / 2;
+ int level2 = 63 - v44134[volume * _v44079[channelNum] / 63];
+ int level1 = !_v44082[channelNum] ? 63 - _v44070[channelNum] :
+ 63 - v44134[volume * _v44070[channelNum] / 63];
+
+ int portNum = v440C2[v440B0[channelNum]] + 0x40;
+ write(portNum, (_portContents[portNum] & 0x80) | level1);
+
+ portNum = v440C2[v440B9[channelNum]] + 0x40;
+ write(portNum, (_portContents[portNum] & 0x80) | level2);
+}
+
+void AdlibFxSoundDriver::setVoice(int channel) {
+ int portNum = 0xB0 + channel;
+ write(portNum, _portContents[portNum] | 0x20);
+ _channelVoiced[channel] = true;
+}
+
+void AdlibFxSoundDriver::clearVoice(int channel) {
+ write(0xB0 + channel, _portContents[0xB0 + channel] & ~0x20);
+ _channelVoiced[channel] = false;
+}
+
+void AdlibFxSoundDriver::updateChannel(int channel) {
+/*
+ const byte *dataP = _patchData + _v4409E[channel];
+ int portOffset = v440C2[v440B0[channel]];
+
+ int portNum = portOffset + 0x20;
+ int portValue = 0;
+ if (*(dataP + 4))
+ portValue |= 0x80;
+ if (*(dataP + 5))
+ portValue |= 0x40;
+ if (*(dataP + 8))
+ portValue |= 0x20;
+ if (*(dataP + 6))
+ portValue |= 0x10;
+ portValue |= *(dataP + 7);
+ write(portNum, portValue);
+
+ portValue = (_portContents[0x40 + portOffset] & 0x3F) | (*(dataP + 9) << 6);
+ write(0x40 + portOffset, portValue);
+
+ _v44070[channel] = 63 - *(dataP + 10);
+ write(0x60 + portOffset, *(dataP + 12) | (*(dataP + 11) << 4));
+ write(0x80 + portOffset, *(dataP + 14) | (*(dataP + 13) << 4));
+ write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 15));
+
+ portOffset = v440C2[v440B9[channel]];
+ portNum = portOffset + 0x20;
+ portValue = 0;
+ if (*(dataP + 17))
+ portValue |= 0x80;
+ if (*(dataP + 18))
+ portValue |= 0x40;
+ if (*(dataP + 21))
+ portValue |= 0x20;
+ if (*(dataP + 19))
+ portValue |= 0x10;
+ portValue |= *(dataP + 20);
+ write(portNum, portValue);
+
+ write(0x40 + portOffset, (_portContents[0x40 + portOffset] & 0x3f) | (*(dataP + 22) << 6));
+ _v44079[channel] = 0x3F - *(dataP + 23);
+ write(0x60 + portOffset, *(dataP + 25) | (*(dataP + 24) << 4));
+ write(0x80 + portOffset, *(dataP + 27) | (*(dataP + 26) << 4));
+ write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 28));
+
+ write(0xC0 + channel, (_portContents[0xC0 + channel] & 0xF0)
+ | (*(dataP + 16) << 1) | *(dataP + 3));
+
+ _v44082[channel] = *(dataP + 3);
+ */
+}
+
+void AdlibFxSoundDriver::setFrequency(int channel) {
+ int offset, ch;
+
+ int v = _pitchBlend[channel];
+ if (v == 0x2000) {
+ offset = 0;
+ ch = _v44067[channel];
+ } else if (v > 0x2000) {
+ ch = _v44067[channel];
+ v -= 0x2000;
+ if (v == 0x1fff)
+ v = 0x2000;
+
+ offset = (v / 170) & 3;
+ ch += (v / 170) >> 2;
+
+ if (ch >= 128)
+ ch = 127;
+ } else {
+ ch = _v44067[channel];
+ int tempVal = (0x2000 - v) / 170;
+ int tempVal2 = 4 - (tempVal & 3);
+
+ if (tempVal2 == 4)
+ offset = 0;
+ else {
+ offset = tempVal2;
+ --ch;
+ }
+
+ ch -= tempVal >> 2;
+ if (ch < 0)
+ ch = 0;
+ }
+
+ int var2 = ch / 12;
+ if (var2)
+ --var2;
+
+ int dataWord = v440D4[((ch % 12) << 2) + offset];
+ write(0xA0 + channel, dataWord & 0xff);
+ write(0xB0 + channel, (_portContents[0xB0 + channel] & 0xE0) |
+ ((dataWord >> 8) & 3) | (var2 << 2));
+}
+
+int AdlibFxSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
+ update(buffer, numSamples);
+ return numSamples;
+}
+
+void AdlibFxSoundDriver::update(int16 *buf, int len) {
+ static int samplesLeft = 0;
+ while (len != 0) {
+ int count = samplesLeft;
+ if (count > len) {
+ count = len;
+ }
+ samplesLeft -= count;
+ len -= count;
+ YM3812UpdateOne(_opl, buf, count);
+ if (samplesLeft == 0) {
+ flush();
+ samplesLeft = _sampleRate / 50;
+ }
+ buf += count;
+ }
}
} // End of namespace tSage
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 03ae77b703..27f30b9b08 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -24,23 +24,489 @@
#define TSAGE_SOUND_H
#include "common/scummsys.h"
+#include "common/mutex.h"
+#include "common/queue.h"
+#include "audio/audiostream.h"
+#include "audio/fmopl.h"
+#include "audio/mixer.h"
+#include "common/list.h"
#include "tsage/saveload.h"
+#include "tsage/core.h"
namespace tSage {
+class Sound;
+
+#define SOUND_ARR_SIZE 16
+#define ROLAND_DRIVER_NUM 2
+#define ADLIB_DRIVER_NUM 3
+
+struct trackInfoStruct {
+ int _numTracks;
+ int _chunks[SOUND_ARR_SIZE];
+ int _voiceTypes[SOUND_ARR_SIZE];
+};
+
+enum SoundDriverStatus {SNDSTATUS_FAILED = 0, SNDSTATUS_DETECTED = 1, SNDSTATUS_SKIPPED = 2};
+enum VoiceType {VOICETYPE_0 = 0, VOICETYPE_1 = 1};
+
+class SoundDriverEntry {
+public:
+ int driverNum;
+ SoundDriverStatus status;
+ int field2, field6;
+ Common::String shortDescription;
+ Common::String longDescription;
+};
+
+struct GroupData {
+ uint32 groupMask;
+ byte v1;
+ byte v2;
+ const byte *pData;
+};
+
+struct RegisterValue {
+ uint8 _regNum;
+ uint8 _value;
+
+ RegisterValue(int regNum, int value) {
+ _regNum = regNum; _value = value;
+ }
+};
+
+class SoundDriver {
+public:
+ Common::String _shortDescription, _longDescription;
+ int _minVersion, _maxVersion;
+ // The following fields were originally held in separate arrays in the SoundManager class
+ uint32 _groupMask;
+ const GroupData *_groupOffset;
+ int _driverResID;
+public:
+ SoundDriver();
+ virtual ~SoundDriver() {};
+
+ const Common::String &getShortDriverDescription() { return _shortDescription; }
+ const Common::String &getLongDriverDescription() { return _longDescription; }
+
+ virtual bool open() { return true; } // Method #0
+ virtual void close() {} // Method #1
+ virtual bool reset() { return true; } // Method #2
+ 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 int setMasterVolume(int volume) { return 0; } // Method #7
+ virtual void proc16() {} // Method #8
+ virtual void proc18(int al, VoiceType voiceType) {} // Method #9
+ virtual void proc20(int al, VoiceType voiceType) {} // Method #10
+ virtual void proc22(int al, VoiceType voiceType, int v3) {} // Method #11
+ virtual void proc24(int channel, int voiceIndex, Sound *sound, int v1, int v2) {}
+ virtual void setProgram(int channel, int program) {} // Method #13
+ virtual void setVolume1(int channel, int v2, int v3, int volume) {}
+ virtual void setPitchBlend(int channel, int pitchBlend) {} // Method #15
+ virtual void proc32(int channel, int program, int v0, int v1) {}// Method #16
+ virtual void updateVoice(int channel) {} // Method #17
+ virtual void proc36() {} // Method #18
+ virtual void proc38(int channel, int cmd, int value) {} // Method #19
+ virtual void setPitch(int channel, int pitchBlend) {} // Method #20
+ virtual void proc42(int channel, int v0, int v1) {} // Method #21
+};
+
+struct VoiceStructEntryType0 {
+ Sound *_sound;
+ int _channelNum;
+ int _priority;
+ int _fieldA;
+ Sound *_sound2;
+ int _channelNum2;
+ int _priority2;
+ int _field12;
+ Sound *_sound3;
+ int _channelNum3;
+ int _priority3;
+ int _field1A;
+};
+
+struct VoiceStructEntryType1 {
+ int _field4;
+ int _field5;
+ int _field6;
+ Sound *_sound;
+ int _channelNum;
+ int _priority;
+ Sound *_sound2;
+ int _channelNum2;
+ int _priority2;
+ Sound *_sound3;
+ int _channelNum3;
+ int _priority3;
+};
+
+struct VoiceStructEntry {
+ int _voiceNum;
+ int _field1;
+ SoundDriver *_driver;
+
+ VoiceStructEntryType0 _type0;
+ VoiceStructEntryType1 _type1;
+};
+
+class VoiceTypeStruct {
+public:
+ VoiceType _voiceType;
+ int _total;
+ int _numVoices;
+ int _field3;
+
+ Common::Array<VoiceStructEntry> _entries;
+};
+
class SoundManager : public SaveListener {
+private:
+ SoundDriver *instantiateDriver(int driverNum);
public:
- void dispatch() {}
+ bool __sndmgrReady;
+ int _ourSndResVersion, _ourDrvResVersion;
+ SynchronizedList<Sound *> _playList;
+ Common::List<SoundDriver *> _installedDrivers;
+ VoiceTypeStruct *_voiceTypeStructPtrs[SOUND_ARR_SIZE];
+ uint32 _groupsAvail;
+ int _masterVol;
+ int _newVolume;
+ Common::Mutex _serverDisabledMutex;
+ Common::Mutex _serverSuspendedMutex;
+ bool _driversDetected;
+ SynchronizedList<Sound *> _soundList;
+ Common::List<SoundDriverEntry> _availableDrivers;
+ bool _needToRethink;
+ // Misc flags
+ bool _soTimeIndexFlag;
+public:
+ SoundManager();
+ ~SoundManager();
+
+ void dispatch();
virtual void listenerSynchronize(Serializer &s);
virtual void postInit();
+ void syncSounds();
+ void update();
- void proc2() {}
static void saveNotifier(bool postFlag);
void saveNotifierProc(bool postFlag);
static void loadNotifier(bool postFlag);
void loadNotifierProc(bool postFlag);
+
+ void installConfigDrivers();
+ Common::List<SoundDriverEntry> &buildDriverList(bool detectFlag);
+ Common::List<SoundDriverEntry> &getDriverList(bool detectFlag);
+ void dumpDriverList();
+ void installDriver(int driverNum);
+ bool isInstalled(int driverNum) const;
+ void unInstallDriver(int driverNum);
+ void checkResVersion(const byte *soundData);
+ int determineGroup(const byte *soundData);
+ int extractPriority(const byte *soundData);
+ int extractLoop(const byte *soundData);
+ bool isOnPlayList(Sound *sound);
+ void extractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum);
+ void addToSoundList(Sound *sound);
+ void removeFromSoundList(Sound *sound);
+ void addToPlayList(Sound *sound);
+ void removeFromPlayList(Sound *sound);
+ void rethinkVoiceTypes();
+ void updateSoundVol(Sound *sound);
+ void updateSoundPri(Sound *sound);
+ void updateSoundLoop(Sound *sound);
+ void setMasterVol(int volume);
+ int getMasterVol() const;
+ void loadSound(int soundNum, bool showErrors);
+ void unloadSound(int soundNum);
+
+ // _sf methods
+ static SoundManager &sfManager();
+ static void _sfTerminate();
+ static int _sfDetermineGroup(const byte *soundData);
+ static void _sfAddToPlayList(Sound *sound);
+ static void _sfRemoveFromPlayList(Sound *sound);
+ static bool _sfIsOnPlayList(Sound *sound);
+ static void _sfRethinkSoundDrivers();
+ static void _sfRethinkVoiceTypes();
+ static void _sfUpdateVolume(Sound *sound);
+ static void _sfDereferenceAll();
+ static void _sfUpdatePriority(Sound *sound);
+ static void _sfUpdateLoop(Sound *sound);
+ static void _sfSetMasterVol(int volume);
+ static void _sfExtractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum);
+ static void _sfExtractGroupMask();
+ static bool _sfInstallDriver(SoundDriver *driver);
+ static void _sfUnInstallDriver(SoundDriver *driver);
+ static void _sfInstallPatchBank(SoundDriver *driver, const byte *bankData);
+ static void _sfDoAddToPlayList(Sound *sound);
+ static bool _sfDoRemoveFromPlayList(Sound *sound);
+ static void _sfDoUpdateVolume(Sound *sound);
+ static void _sfSoundServer();
+ static void _sfProcessFading();
+ static void _sfUpdateVoiceStructs();
+ static void _sfUpdateVoiceStructs2();
+ static void _sfUpdateCallback(void *ref);
};
+class Sound: public EventHandler {
+private:
+ void _prime(int soundResID, bool dontQueue);
+ void _unPrime();
+public:
+ bool _stoppedAsynchronously;
+ int _soundResID;
+ int _group;
+ int _sndResPriority;
+ int _fixedPriority;
+ int _sndResLoop;
+ int _fixedLoop;
+ int _priority;
+ int _volume;
+ int _loop;
+ int _pausedCount;
+ int _mutedCount;
+ int _hold;
+ int _cueValue;
+ int _fadeDest;
+ int _fadeSteps;
+ int _fadeTicks;
+ int _fadeCounter;
+ bool _stopAfterFadeFlag;
+ uint32 _timer;
+ uint32 _newTimeIndex;
+ int _loopTimer;
+ int _chProgram[SOUND_ARR_SIZE];
+ int _chModulation[SOUND_ARR_SIZE];
+ int _chVolume[SOUND_ARR_SIZE];
+ int _chPan[SOUND_ARR_SIZE];
+ int _chDamper[SOUND_ARR_SIZE];
+ int _chPitchBlend[SOUND_ARR_SIZE];
+ int _chVoiceType[SOUND_ARR_SIZE];
+ int _chNumVoices[SOUND_ARR_SIZE];
+ int _chSubPriority[SOUND_ARR_SIZE];
+ int _chFlags[SOUND_ARR_SIZE];
+ bool _chWork[SOUND_ARR_SIZE];
+ trackInfoStruct _trackInfo;
+ byte *_channelData[SOUND_ARR_SIZE];
+ int _trkChannel[SOUND_ARR_SIZE];
+ int _trkState[SOUND_ARR_SIZE];
+ int _trkLoopState[SOUND_ARR_SIZE];
+ int _trkIndex[SOUND_ARR_SIZE];
+ int _trkLoopIndex[SOUND_ARR_SIZE];
+ int _trkRest[SOUND_ARR_SIZE];
+ int _trkLoopRest[SOUND_ARR_SIZE];
+
+ bool _primed;
+ bool _isEmpty;
+ byte *_remoteReceiver;
+public:
+ Sound();
+ ~Sound();
+
+ void synchronize(Serializer &s);
+ void orientAfterRestore();
+
+ void play(int soundResID);
+ void stop();
+ void prime(int soundResID);
+ void unPrime();
+ void go();
+ void halt(void);
+ bool isPlaying();
+ int getSoundNum() const;
+ bool isPrimed() const;
+ bool isPaused() const;
+ bool isMuted() const;
+ void pause(bool flag);
+ void mute(bool flag);
+ void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag);
+ void setTimeIndex(uint32 timeIndex);
+ uint32 getTimeIndex() const;
+ int getCueValue() const;
+ void setCueValue(int cueValue);
+ void setVol(int volume);
+ int getVol() const;
+ void setPri(int priority);
+ void setLoop(int flag);
+ int getPri() const;
+ int getLoop();
+ void holdAt(int amount);
+ void release();
+ void orientAfterDriverChange();
+
+ // _so methods
+ void _soPrimeSound(bool dontQueue);
+ void _soSetTimeIndex(uint timeIndex);
+ bool _soServiceTracks();
+ void _soPrimeChannelData();
+ void _soRemoteReceive();
+ void _soServiceTrackType0(int trackIndex, const byte *channelData);
+ void _soUpdateDamper(VoiceTypeStruct *voiceType, int channelNum, VoiceType mode, int v0);
+ void _soProc32(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0, int v1);
+ void _soProc42(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0);
+ void _soProc38(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int cmd, int value);
+ void _soProc40(VoiceTypeStruct *vtStruct, int channelNum, int pitchBlend);
+ void _soDoTrackCommand(int channelNum, int command, int value);
+ bool _soDoUpdateTracks(int command, int value);
+ void _soSetTrackPos(int trackIndex, int trackPos, int cueValue);
+
+ void _soServiceTrackType1(int trackIndex, const byte *channelData);
+ int _soFindSound(VoiceTypeStruct *vtStruct, int channelNum);
+};
+
+class ASound: public EventHandler {
+public:
+ Sound _sound;
+ Action *_action;
+ int _cueValue;
+
+ ASound();
+ ~ASound();
+ virtual void synchronize(Serializer &s);
+ virtual void dispatch();
+
+ void play(int soundNum, Action *action = NULL, int volume = 127);
+ void stop();
+ void prime(int soundNum, Action *action = NULL);
+ void unPrime();
+ void go() { _sound.go(); }
+ void hault(void) { _sound.halt(); }
+ bool isPlaying() { return _sound.isPlaying(); }
+ int getSoundNum() const { return _sound.getSoundNum(); }
+ bool isPaused() const { return _sound.isPaused(); }
+ 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, Action *action);
+ 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); }
+ uint32 getTimeIndex() const { return _sound.getTimeIndex(); }
+ void setPri(int v) { _sound.setPri(v); }
+ void setLoop(int total) { _sound.setLoop(total); }
+ int getPri() const { return _sound.getPri(); }
+ int getLoop() { return _sound.getLoop(); }
+ void setVol(int volume) { _sound.setVol(volume); }
+ int getVol() const { return _sound.getVol(); }
+ void holdAt(int v) { _sound.holdAt(v); }
+ void release() { _sound.release(); }
+};
+
+#define ADLIB_CHANNEL_COUNT 9
+
+class AdlibSoundDriver: public SoundDriver, Audio::AudioStream {
+private:
+ GroupData _groupData;
+ Audio::Mixer *_mixer;
+ FM_OPL *_opl;
+ Audio::SoundHandle _soundHandle;
+ int _sampleRate;
+ byte _portContents[256];
+ const byte *_patchData;
+ int _masterVolume;
+ Common::Queue<RegisterValue> _queue;
+
+ bool _channelVoiced[ADLIB_CHANNEL_COUNT];
+ int _channelVolume[ADLIB_CHANNEL_COUNT];
+ int _v4405E[ADLIB_CHANNEL_COUNT];
+ int _v44067[ADLIB_CHANNEL_COUNT];
+ int _v44070[ADLIB_CHANNEL_COUNT];
+ int _v44079[ADLIB_CHANNEL_COUNT];
+ int _v44082[ADLIB_CHANNEL_COUNT + 1];
+ int _pitchBlend[ADLIB_CHANNEL_COUNT];
+ int _v4409E[ADLIB_CHANNEL_COUNT];
+
+
+ void write(byte reg, byte value);
+ void flush();
+ void updateChannelVolume(int channel);
+ void setVoice(int channel);
+ void clearVoice(int channel);
+ void updateChannel(int channel);
+ void setFrequency(int channel);
+public:
+ AdlibSoundDriver();
+ virtual ~AdlibSoundDriver();
+
+ virtual bool open();
+ virtual void close();
+ virtual bool reset();
+ virtual const GroupData *getGroupData();
+ virtual void installPatch(const byte *data, int size);
+ virtual int setMasterVolume(int volume);
+ virtual void proc32(int channel, int program, int v0, int v1);
+ virtual void updateVoice(int channel);
+ virtual void proc38(int channel, int cmd, int value);
+ virtual void setPitch(int channel, int pitchBlend);
+
+ // AudioStream interface
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+ virtual bool isStereo() const { return false; }
+ virtual bool endOfData() const { return false; }
+ virtual int getRate() const { return _sampleRate; }
+
+ void update(int16 *buf, int len);
+};
+
+class AdlibFxSoundDriver: public SoundDriver, Audio::AudioStream {
+private:
+ GroupData _groupData;
+ Audio::Mixer *_mixer;
+ FM_OPL *_opl;
+ Audio::SoundHandle _soundHandle;
+ int _sampleRate;
+ byte _portContents[256];
+ int _masterVolume;
+ Common::Queue<RegisterValue> _queue;
+
+ bool _channelVoiced[ADLIB_CHANNEL_COUNT];
+ int _channelVolume[ADLIB_CHANNEL_COUNT];
+ int _v4405E[ADLIB_CHANNEL_COUNT];
+ int _v44067[ADLIB_CHANNEL_COUNT];
+ int _v44070[ADLIB_CHANNEL_COUNT];
+ int _v44079[ADLIB_CHANNEL_COUNT];
+ int _v44082[ADLIB_CHANNEL_COUNT + 1];
+ int _pitchBlend[ADLIB_CHANNEL_COUNT];
+ int _v4409E[ADLIB_CHANNEL_COUNT];
+
+
+ void write(byte reg, byte value);
+ void flush();
+ void updateChannelVolume(int channel);
+ void setVoice(int channel);
+ void clearVoice(int channel);
+ void updateChannel(int channel);
+ void setFrequency(int channel);
+public:
+ AdlibFxSoundDriver();
+ virtual ~AdlibFxSoundDriver();
+
+ virtual bool open();
+ virtual void close();
+ virtual bool reset();
+ virtual const GroupData *getGroupData();
+ virtual void installPatch(const byte *data, int size) {}
+ virtual int setMasterVolume(int volume);
+ virtual void proc32(int channel, int program, int v0, int v1);
+ virtual void updateVoice(int channel);
+ virtual void proc38(int channel, int cmd, int value);
+ virtual void setPitch(int channel, int pitchBlend);
+
+ // AudioStream interface
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+ virtual bool isStereo() const { return false; }
+ virtual bool endOfData() const { return false; }
+ virtual int getRate() const { return _sampleRate; }
+
+ void update(int16 *buf, int len);
+};
+
+
} // End of namespace tSage
#endif
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
index 50ce0ce4be..41f3d58897 100644
--- a/engines/tsage/tsage.cpp
+++ b/engines/tsage/tsage.cpp
@@ -81,12 +81,17 @@ void TSageEngine::initialize() {
_globals = new Globals();
_globals->gfxManager().setDefaults();
+
+ // Setup sound settings
+ syncSoundSettings();
}
void TSageEngine::deinitialize() {
delete _globals;
delete _resourceManager;
delete _saver;
+ _resourceManager = NULL;
+ _saver = NULL;
}
Common::Error TSageEngine::run() {
@@ -136,4 +141,10 @@ Common::String TSageEngine::generateSaveName(int slot) {
return Common::String::format("%s.%03d", _targetName.c_str(), slot);
}
+void TSageEngine::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _globals->_soundManager.syncSounds();
+}
+
} // End of namespace tSage
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index 563fdfcc21..f004c7f625 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -23,7 +23,6 @@
#ifndef TSAGE_H
#define TSAGE_H
-#include "engines/advancedDetector.h"
#include "engines/engine.h"
#include "common/rect.h"
#include "audio/mixer.h"
@@ -52,7 +51,9 @@ enum {
};
enum {
- kRingDebugScripts = 1 << 0
+ kRingDebugScripts = 1 << 0,
+ ktSageSound = 1 << 1,
+ ktSageCore = 1 << 2
};
struct tSageGameDescription;
@@ -84,6 +85,7 @@ public:
virtual bool canSaveGameStateCurrently();
virtual Common::Error loadGameState(int slot);
virtual Common::Error saveGameState(int slot, const Common::String &desc);
+ virtual void syncSoundSettings();
Common::String generateSaveName(int slot);
void initialize();
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp
index 31d9caef73..4a3313e3f7 100644
--- a/engines/tucker/detection.cpp
+++ b/engines/tucker/detection.cpp
@@ -102,31 +102,6 @@ static const ADGameDescription tuckerGameDescriptions[] = {
AD_TABLE_END_MARKER
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)tuckerGameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 512,
- // List of all engine targets
- tuckerGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "tucker",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game)
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
static const ADGameDescription tuckerDemoGameDescription = {
"tucker",
"Non-Interactive Demo",
@@ -139,7 +114,9 @@ static const ADGameDescription tuckerDemoGameDescription = {
class TuckerMetaEngine : public AdvancedMetaEngine {
public:
- TuckerMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TuckerMetaEngine() : AdvancedMetaEngine(tuckerGameDescriptions, sizeof(ADGameDescription), tuckerGames) {
+ _md5Bytes = 512;
+ _singleid = "tucker";
}
virtual const char *getName() const {
@@ -168,7 +145,7 @@ public:
return desc != 0;
}
- virtual const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const {
+ virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
for (Common::FSList::const_iterator d = fslist.begin(); d != fslist.end(); ++d) {
Common::FSList audiofslist;
if (d->isDirectory() && d->getName().equalsIgnoreCase("audio") && d->getChildren(audiofslist, Common::FSNode::kListFilesOnly)) {